docs: function (rootComp) {
        var self = this;
        var stop = false;
        var renderQueue = [];
  
        var transitionState = function () {
          var stateChanged, metaChanged;
  
          if (renderQueue.length === 1) {
            var singleFrame = renderQueue[0];
  
            stateChanged = singleFrame.stateChanged;
            metaChanged = singleFrame.metaChanged;
  
            if (stateChanged) self._previousState = singleFrame.previousState;
            if (metaChanged) self._previousMetaState = singleFrame.previousMetaState;
          } else {
            var elderStateChangedFrame = Util.find(renderQueue, function (q) { return q.stateChanged; });
            var elderMetaChangedFrame = Util.find(renderQueue, function (q) { return q.metaChanged; });
  
            stateChanged = !!elderStateChangedFrame;
            metaChanged = !!elderMetaChangedFrame;
  
            if (stateChanged) self._previousState = elderStateChangedFrame.previousState;
            if (metaChanged) self._previousMetaState = elderMetaChangedFrame.previousMetaState;
          }
  
          self._stateChanged = stateChanged;
          self._metaChanged = metaChanged;
  
          renderQueue = [];
        };
  
        var forceUpdate = function (comp, f) {
          if (comp.isMounted()) {
            comp.forceUpdate(f);
          }
        };
  
        var logError = function (message, cause) {
          if (self._options.logger) {
            try {
              self._options.logger.error(message, cause);
            }
            catch (e) {
              defaultLogger.error(message, cause);
            }
          }
        };
  
        var catchingRenderErrors = function (f) {
          try {
            f();
          } catch (e) {
            if (self._options.stopOnRenderError) {
              stop = true;
            }
  
            logError('Morearty: render error. ' + (stop ? 'Will exit on next render attempt.' : 'Continuing.'), e);
          }
        };
  
        var render = function () {
          transitionState();
  
          self._renderQueued = false;
  
          catchingRenderErrors(function () {
            if (self._fullUpdateQueued) {
              self._fullUpdateInProgress = true;
  
              forceUpdate(rootComp, function () {
                self._fullUpdateQueued = false;
                self._fullUpdateInProgress = false;
              });
            } else {
              forceUpdate(rootComp);
  
              self._componentQueue.forEach(function (c) {
                forceUpdate(c);
                savePreviousState(c);
              });
              self._componentQueue = [];
            }
          });
        };
  
        if (!self._options.renderOnce) {
          var renderRoutine = getRenderRoutine(self);
  
          var listenerId = self._stateBinding.addListener(function (changes) {
            if (stop) {
              self._stateBinding.removeListener(listenerId);
            } else {
              var stateChanged = changes.isValueChanged(), metaChanged = changes.isMetaChanged();
  
              if (stateChanged || metaChanged) {
                renderQueue.push({
                  stateChanged: stateChanged,
                  metaChanged: metaChanged,
                  previousState: (stateChanged || null) && changes.getPreviousBackingValue(),
                  previousMetaState: (metaChanged || null) && changes.getPreviousBackingMeta()
                });
  
                if (!self._renderQueued) {
                  self._renderQueued = true;
                  renderRoutine(render);
                }
              }
            }
          });
        }
  
        catchingRenderErrors(rootComp.forceUpdate.bind(rootComp));
      }