/**
  * Loads all events available in the event store and calls
  * {@link \Governor\Framework\EventStore\EventVisitorInterface::doWithEvent}
  * for each event found. Events of a single aggregate are guaranteed to be ordered by their sequence number.
  * <p/>
  * Implementations are encouraged, though not required, to supply events in the absolute chronological order.
  * <p/>
  * Processing stops when the visitor throws an exception.
  *
  * @param EventVisitorInterface $visitor The visitor the receives each loaded event
  * @param CriteriaInterface $criteria The criteria describing the events to select.
  */
 public function visitEvents(EventVisitorInterface $visitor, CriteriaInterface $criteria = null)
 {
     $params = isset($criteria) ? $criteria->asMongoObject() : [];
     $cursor = $this->storageStrategy->findEventsByCriteria($this->mongoTemplate->domainEventCollection(), $params);
     //cursor.addOption(Bytes.QUERYOPTION_NOTIMEOUT);
     $self = $this;
     $cb = function (array $entry, $identifier) use($self) {
         return $self->storageStrategy->extractEventMessages($entry, $identifier, $self->eventSerializer, $self->upcasterChain, false);
     };
     $events = new CursorBackedDomainEventStream($cursor, [], null, null, true, $cb);
     try {
         while ($events->hasNext()) {
             $visitor->doWithEvent($events->next());
         }
     } finally {
         $events->close();
     }
 }