anchor.diff:        }
       }
       // remove existing items
  -    rows.forEach((key, row){
  +    _rows.forEach((key, row){
         row.block.remove();
         row.scope.$destroy();
       });
  -    rows = newRows;
  +    _rows = newRows;
       return newRowOrder;
     }
   
     _onCollectionChange(collection) {
  -    var previousNode = blockHole.elements[0],     // current position of the node
  +    var previousNode = _blockHole.elements[0],     // current position of the node
           nextNode,
           childScope,
           trackById,
  -        cursor = blockHole;
  +        cursor = _blockHole;
   
       if (collection is! List) {
         collection = [];
  
positive.code:     selector: '[ng-repeat]',
      map: const {'.': '@.expression'})
  class NgRepeatDirective  {
    static RegExp SYNTAX = new RegExp(r'^\s*(.+)\s+in\s+(.*?)\s*(\s+track\s+by\s+(.+)\s*)?$');
    static RegExp LHS_SYNTAX = new RegExp(r'^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$');
  
    BlockHole blockHole;
    BoundBlockFactory boundBlockFactory;
    Scope scope;
  
    String _expression;
    String valueIdentifier;
    String keyIdentifier;
    String listExpr;
    Map<Object, _Row> rows = new Map<dynamic, _Row>();
    Function trackByIdFn = (key, value, index) => value;
    Function removeWatch = () => null;
  
    NgRepeatDirective(BlockHole this.blockHole,
                          BoundBlockFactory this.boundBlockFactory,
                          Scope this.scope);
  
    set expression(value) {
      _expression = value;
      removeWatch();
      Match match = SYNTAX.firstMatch(_expression);
      if (match == null) {
        throw "[NgErr7] ngRepeat error! Expected expression in form of '_item_ in _collection_[ track by _id_]' but got '$_expression'.";
      }
      listExpr = match.group(2);
      var assignExpr = match.group(1);
      match = LHS_SYNTAX.firstMatch(assignExpr);
      if (match == null) {
        throw "[NgErr8] ngRepeat error! '_item_' in '_item_ in _collection_' should be an identifier or '(_key_, _value_)' expression, but got '$assignExpr'.";
      }
      valueIdentifier = match.group(3);
      if (valueIdentifier == null) valueIdentifier = match.group(1);
      keyIdentifier = match.group(2);
  
      removeWatch = scope.$watchCollection(listExpr, _onCollectionChange);
    }
  
    List<_Row> _computeNewRows(collection, trackById) {
  
negative.code:     var length = newRowOrder.length = collection.length;
      for (var index = 0; index < length; index++) {
        var value = collection[index];
        trackById = _trackByIdFn(index, value, index);
        if (_rows.containsKey(trackById)) {
          var row = _rows[trackById];
          _rows.remove(trackById);
          newRows[trackById] = row;
          newRowOrder[index] = row;
        } else if (newRows.containsKey(trackById)) {
          // restore lastBlockMap
          newRowOrder.forEach((row) {
            if (row != null && row.startNode != null) {
              _rows[row.id] = row;
            }
          });
          // This is a duplicate and we need to throw an error
  