docs: function() {
        var i,
            self = this;
  
        // Cleanup previous "on" and "listenTo" events
        for (i = 0; i < this.__feedbackOnEvents.length; i++) {
          this.off(null, this.__feedbackOnEvents[i]);
        }
        for (i = 0; i < this.__feedbackListenToEvents.length; i++) {
          var feedbackListenToConfig = this.__feedbackListenToEvents[i];
          this.stopListening(feedbackListenToConfig.obj, feedbackListenToConfig.name, feedbackListenToConfig.callback);
        }
        this.__feedbackOnEvents = [];
        this.__feedbackListenToEvents = [];
  
        // For each feedback configuration
        _.each(this.feedback, function(declaration) {
          var toEntries = [declaration.to];
          if (_.isArray(declaration.to)) {
            toEntries = declaration.to;
          }
          _.each(toEntries, function(to) {
            var destinations = self.__getFeedbackDestinations(to),
              destIndexTokens = self.__getAllIndexTokens(to);
  
            // Iterate over all destinations
            _.each(destinations, function(dest) {
              var fieldName, indices, indexMap, then, args, method, whenEvents, bindInfo;
              dest = $(dest);
              fieldName = dest.data('feedback');
              indices = self.__getAllIndexTokens(fieldName);
              indexMap = {};
              // Generates a mapping from variable name to value:
              // If the destination "to" mapping is: my-feedback-element[x][y] and this particular destination is: my-feedback-element[1][4]
              // then the map would look like: {x: 1, y: 4}
              _.each(destIndexTokens, function(indexToken, i) {
                indexMap[indexToken] = indices[i];
              });
              then = declaration.then;
  
              // If the "then" clause is a string, assume it's a view method
              if (_.isString(then)) {
                then = self[then];
              } else if (_.isArray(then)) {
                // If the "then" clause is an array, assume it's [viewMethod, arg[0], arg[1], ...]
                args = then.slice();
                method = args[0];
                args.shift();
                then = self[method].apply(self, args);
              }
  
              // track the indices for binding
              bindInfo = {
                feedbackCellField: fieldName,
                fn: then,
                indices: indexMap
              };
              // Iterate over all "when" clauses
              whenEvents = self.__generateWhenEvents(declaration.when, indexMap);
              _.each(whenEvents, function(eventKey) {
                var match, delegateEventSplitter,
                  invokeThen = function(evt) {
                    var i, args, result, newState;
                    args = [evt];
                    newState = {};
                    args.push(bindInfo.indices);
                    result = bindInfo.fn.apply(self, args);
                    self.__processFeedbackThenResult(result, bindInfo.feedbackCellField);
                  };
                delegateEventSplitter = /^(\S+)\s*(.*)$/;
                match = eventKey.match(delegateEventSplitter);
                self.$el.on(match[1] + '.delegateEvents' + self.cid, match[2], _.bind(invokeThen, self));
              });
              // Special "on" listeners
              _.each(declaration.when.on, function(eventKey) {
                var invokeThen = self.__generateThenCallback(bindInfo, eventKey);
                self.on(eventKey, invokeThen, self);
                self.__feedbackOnEvents.push(invokeThen);
              });
              // Special "listenTo" listeners
              _.each(declaration.when.listenTo, function(listenToConfig) {
                var obj = listenToConfig.object;
                if (_.isFunction(obj)) {
                  obj = _.bind(listenToConfig.object, self)();
                } else if (_.isString(obj)) {
                  obj = _.result(self, listenToConfig.object);
                }
                if (obj) {
                  var invokeThen = _.bind(self.__generateThenCallback(bindInfo, listenToConfig.events), self);
                  self.listenTo(obj, listenToConfig.events, invokeThen);
                  self.__feedbackListenToEvents.push({
                    object: obj,
                    name: listenToConfig.events,
                    callback: invokeThen
                  });
                }
              });
            });
          });
        });
      }