anchor.diff:    String _valueIdentifier;
     String _keyIdentifier;
     String _listExpr;
  -  List<_Row> _rows;
  +  List<View> _views;
     Function _generateId = (key, value, index) => value;
     Watch _watch;
   
  
positive.code:     _watch = _scope.watch(
          _listExpr,
          (changes, _) {
            _onChange((changes is CollectionChangeRecord) ? changes : null);
          },
          collection: true,
          formatters: formatters
      );
    }
  
    // Computes and executes DOM changes when the item list changes
    void _onChange(CollectionChangeRecord changes) {
      final iterable = (changes == null) ? const [] : changes.iterable;
      final int length = (changes == null) ? 0 : changes.length;
      final rows = new List<_Row>(length);
      final changeFunctions = new List<Function>(length);
      final removedIndexes = <int>[];
      final int domLength = _rows == null ? 0 : _rows.length;
      final leftInDom = new List.generate(domLength, (i) => domLength - 1 - i);
      var domIndex;
  
      var addRow = (int index, value, View previousView) {
        var childContext = _updateContext(new PrototypeMap(_scope.context), index,
            length)..[_valueIdentifier] = value;
        var childScope = _scope.createChild(childContext);
        var view = _boundViewFactory(childScope);
        var nodes = view.nodes;
        rows[index] = new _Row(_generateId(index, value, index))
            ..view = view
            ..scope = childScope
            ..nodes = nodes
            ..startNode = nodes.first
            ..endNode = nodes.last;
        _viewPort.insert(view, insertAfter: previousView);
      };
  
      // todo(vicb) refactor once GH-774 gets fixed
      if (_rows == null) {
        _rows = new List<_Row>(length);
        for (var i = 0; i < length; i++) {
          changeFunctions[i] = (index, previousView) {
            addRow(index, iterable.elementAt(i), previousView);
          };
        }
      } else {
        if (changes == null) {
          _rows.forEach((row) {
            _viewPort.remove(row.view);
          });
          leftInDom.clear();
        } else {
          changes.forEachRemoval((CollectionChangeItem removal) {
            var index = removal.previousIndex;
            var row = _rows[index];
            _viewPort.remove(row.view);
            leftInDom.removeAt(domLength - 1 - index);
          });
  
          changes.forEachAddition((CollectionChangeItem addition) {
            changeFunctions[addition.currentIndex] = (index, previousView) {
              addRow(index, addition.item, previousView);
            };
          });
  
          changes.forEachMove((CollectionChangeItem move) {
            var previousIndex = move.previousIndex;
            var value = move.item;
            changeFunctions[move.currentIndex] = (index, previousView) {
              var previousRow = _rows[previousIndex];
              var childScope = previousRow.scope;
              var childContext = _updateContext(childScope.context, index, length);
              if (!identical(childScope.context[_valueIdentifier], value)) {
                childContext[_valueIdentifier] = value;
              }
              rows[index] = _rows[previousIndex];
              // Only move the DOM node when required
              if (domIndex < 0 || leftInDom[domIndex] != previousIndex) {
                _viewPort.move(previousRow.view, moveAfter: previousView);
                leftInDom.remove(previousIndex);
              }
              domIndex--;
            };
          });
        }
      }
  
      var previousView = null;
      domIndex = leftInDom.length - 1;
      for(var targetIndex = 0; targetIndex < length; targetIndex++) {
        var changeFn = changeFunctions[targetIndex];
        if (changeFn == null) {
          rows[targetIndex] = _rows[targetIndex];
          if (domIndex < 0 || leftInDom[domIndex] != targetIndex) {
            _viewPort.move(rows[targetIndex].view, moveAfter: previousView);
            leftInDom.remove(targetIndex);
          }
          domIndex--;
          // The element has not moved but `$last` and `$middle` might still need to be updated
          _updateContext(rows[targetIndex].scope.context, targetIndex, length);
        } else {
          changeFn(targetIndex, previousView);
        }
        previousView = rows[targetIndex].view;
      }
  
      _rows = rows;
    }
  
    PrototypeMap _updateContext(PrototypeMap context, int index, int length) {
  
negative.code:         ..[r'$even'] = index.isEven;
    }
  }
  