docs: function (evt, callback) {
      if (!this.definition.aggregateId || !dotty.exists(evt, this.definition.aggregateId) ||
          !this.definition.revision || !dotty.exists(evt, this.definition.revision)) {
        var err = new Error('Please define an aggregateId!');
        debug(err);
        return callback(err);
      }
  
      var self = this;
  
      var revInEvt = dotty.get(evt, this.definition.revision);
  
      var concatenatedId = this.getConcatenatedId(evt);
  
      function proceed (revInStore) {
        if (!revInStore && !self.currentHandlingRevisions[concatenatedId] && (self.options.startRevisionNumber === undefined || self.options.startRevisionNumber === null)) {
          self.currentHandlingRevisions[concatenatedId] = revInEvt;
          debug('first revision to store [concatenatedId]=' + concatenatedId + ', [revInStore]=' + (revInStore || 'null') + ', [revInEvt]=' + revInEvt);
          callback(null, function (clb) {
            self.finishGuard(evt, revInStore, clb);
          });
          return;
        }
  
        if (revInStore && revInEvt < revInStore) {
          debug('event already handled [concatenatedId]=' + concatenatedId + ', [revInStore]=' + revInStore + ', [revInEvt]=' + revInEvt);
          callback(new AlreadyHandledError('Event: [id]=' + dotty.get(evt, self.definition.id) + ', [revision]=' + revInEvt + ', [concatenatedId]=' + concatenatedId + ' already handled!'), function (clb) {
            clb(null);
          });
          return;
        }
  
        if (revInStore && revInEvt > revInStore) {
          debug('queue event [concatenatedId]=' + concatenatedId + ', [revInStore]=' + revInStore + ', [revInEvt]=' + revInEvt);
          self.queueEvent(evt, callback);
          return;
        }
  
        if (!revInStore && self.options.startRevisionNumber >= 0 && revInEvt > self.options.startRevisionNumber) {
          debug('queue event (startRevisionNumber is set) [concatenatedId]=' + concatenatedId + ', [startRevisionNumber]=' + self.options.startRevisionNumber + ', [revInEvt]=' + revInEvt);
          self.queueEvent(evt, callback);
          return;
        }
  
        if (!revInStore && self.currentHandlingRevisions[concatenatedId] >= 0 && revInEvt > self.currentHandlingRevisions[concatenatedId]) {
          debug('queue event [concatenatedId]=' + concatenatedId + ', [currentlyHandling]=' + self.currentHandlingRevisions[concatenatedId] + ', [revInEvt]=' + revInEvt);
          self.queueEvent(evt, callback);
          return;
        }
  
        if (self.currentHandlingRevisions[concatenatedId] >= revInEvt) {
          debug('event already handling [concatenatedId]=' + concatenatedId + ', [revInStore]=' + revInStore + ', [revInEvt]=' + revInEvt);
          callback(new AlreadyHandlingError('Event: [id]=' + dotty.get(evt, self.definition.id) + ', [revision]=' + revInEvt + ', [concatenatedId]=' + concatenatedId + ' already handling!'), function (clb) {
            clb(null);
          });
          return;
        }
  
        self.currentHandlingRevisions[concatenatedId] = revInEvt;
  
        debug('event is in correct order => go for it! [concatenatedId]=' + concatenatedId + ', [revInStore]=' + revInStore + ', [revInEvt]=' + revInEvt);
        callback(null, function (clb) {
          self.finishGuard(evt, revInStore, clb);
        });
      }
  
      function retry (max, loop) {
        setTimeout(function () {
          self.store.get(concatenatedId, function(err, revInStore) {
            if (err) {
              debug(err);
              return callback(err);
            }
  
            if (loop <= 0) {
              debug('finished loops for retry => proceed [concatenatedId]=' + concatenatedId + ', [revInStore]=' + revInStore + ', [revInEvt]=' + revInEvt);
              return proceed(revInStore);
            }
  
            if (!revInStore && revInEvt !== 1) {
              debug('no revision in store => retry [concatenatedId]=' + concatenatedId + ', [revInStore]=' + revInStore + ', [revInEvt]=' + revInEvt);
              retry(max, --loop);
              return;
            }
  
            debug('revision in store existing => proceed [concatenatedId]=' + concatenatedId + ', [revInStore]=' + revInStore + ', [revInEvt]=' + revInEvt);
            proceed(revInStore);
          });
        }, randomBetween(max / 5, max));
      }
  
      process.nextTick(function () {
        self.store.get(concatenatedId, function (err, revInStore) {
          if (err) {
            debug(err);
            return callback(err);
          }
  
          if (!revInStore && revInEvt !== (self.options.startRevisionNumber || 1) && !self.currentHandlingRevisions[concatenatedId]) {
            var max = (self.options.queueTimeout * self.options.queueTimeoutMaxLoops) / 3;
            max = max < 10 ? 10 : max;
            retry(max, self.options.queueTimeoutMaxLoops);
            return;
          }
  
          proceed(revInStore);
        });
      });
    }