code: function(stable){
      if(this._mute) return;
      var watchers = !stable? this._watchers: this._watchersForStable;
      var dirty = false, children, watcher, watcherDirty;
      var len = watchers && watchers.length;
      if(len){
        var mark = 0, needRemoved=0;
        for(var i =0; i < len; i++ ){
          watcher = watchers[i];
          var shouldRemove = !watcher ||  watcher.removed;
          if( shouldRemove ){
            needRemoved += 1;
          }else{
            watcherDirty = this._checkSingleWatch(watcher);
            if(watcherDirty) dirty = true;
          }
          // remove when encounter first unmoved item or touch the end
          if( !shouldRemove || i === len-1 ){
            if( needRemoved ){
              watchers.splice(mark, needRemoved );          
              len -= needRemoved;
              i -= needRemoved;
              needRemoved = 0;
            }
            mark = i+1;
          }
        }
      }
      // check children's dirty.
      children = this._children;
      if(children && children.length){
        for(var m = 0, mlen = children.length; m < mlen; m++){
          var child = children[m];
          if(child && child._digest(stable)) dirty = true;
        }
      }
      return dirty;
    }
docs: private digest logic