docs: function (vm, evt, initValues, callback) {
      var self = this;
  
      if (!callback) {
        callback = initValues;
        initValues = null;
      }
  
      var payload = evt;
  
      if (this.payload && this.payload !== '') {
        payload = dotty.get(evt, this.payload);
      }
  
      if (initValues) {
        vm.set(_.cloneDeep(initValues));
      }
  
      var evtId = dotty.get(evt, this.definitions.event.id);
  
      var debugOutPut = evtId ? (', [eventId]=' + evtId) : '';
      debug('[' + this.name + ']' + debugOutPut + ' call denormalizer function');
  
      function retry (retryIn) {
        if (self.collection.isReplaying) {
          var debugMsg = '[' + self.name + ']' + debugOutPut + ' finishing denormalization because is replaying!';
          debug(debugMsg);
          console.log(debugMsg);
          return callback(null);
        }
  
        if (_.isNumber(retryIn)) {
          retryIn = randomBetween(0, retryIn);
        }
  
        if (_.isObject(retryIn) && _.isNumber(retryIn.from) && _.isNumber(retryIn.to)) {
          retryIn = randomBetween(retryIn.from, retryIn.to);
        }
  
        if (!_.isNumber(retryIn) || retryIn === 0) {
          retryIn = randomBetween(0, self.options.retryOnConcurrencyTimeout || 800);
        }
  
        debug('[' + self.name + ']' + debugOutPut + ' retry in ' + retryIn + 'ms');
        setTimeout(function() {
          self.loadViewModel(vm.id, function (err, vm) {
            if (err) {
              debug(err);
              return callback(err);
            }
  
            self.handleOne(vm, evt, initValues, callback);
          });
        }, retryIn);
      }
  
      var shouldBeHandled = function (cb) {
        // if (self.shouldHandleRequestsOnlyEvent) return cb(null, true);
        self.shouldHandle(evt, vm, cb);
      };
  
      shouldBeHandled(function (err, doHandle) {
        if (err) {
          return callback(err);
        }
  
        if (!doHandle) {
          return callback(null, null);
        }
  
        var denormThis = {
          retryCalled: false,
  
          retry: function () {
            denormThis.retryCalled = true;
  
            if (arguments.length === 0) {
              return retry();
            }
  
            if (arguments.length === 1) {
              if (!_.isFunction(arguments[0])) {
                return retry(arguments[0]);
              }
              return retry();
            }
  
            retry(arguments[0]);
          },
  
          toRemember: null,
  
          remindMe: function (memories) {
            denormThis.toRemember = memories;
          },
  
          getReminder: function (memories) {
            return denormThis.toRemember;
          }
        };
  
        self.denormFn.call(denormThis, _.cloneDeep(payload), vm, function (err) {
          if (err) {
            debug(err);
            return callback(err);
          }
  
          var notification = self.generateNotification(evt, vm);
  
          debug('[' + self.name + ']' + debugOutPut + ' generate new id for notification');
          self.getNewId(function (err, newId) {
            if (err) {
              debug(err);
              return callback(err);
            }
  
            dotty.put(notification, self.definitions.notification.id, newId);
  
            self.saveViewModel(vm, function (err) {
              if (err) {
                debug(err);
  
                if (err instanceof ConcurrencyError) {
                  retry(callback);
                  return;
                }
  
                return callback(err);
              }
  
              if (!self.options.callOnAfterCommitDuringReplay && self.collection.isReplaying) {
                return callback(null, notification);
              }
  
              self.handleAfterCommit.call(denormThis, evt, vm, function (err) {
                if (err) {
                  debug(err);
                  return callback(err);
                }
                callback(null, notification);
              });
            });
          });
        });
      });
    }