anchor.diff:           .join()
            .trim();
     
  -    checkEof();
  +    //TODO incorporate this into _readWhile()
  +    _checkEof();
       
       // Check to see if tag name is valid.
       if (tagType != TagType.comment) {    
  
positive.code:       }    
      }
      
      var close = _read();
          
      return new Tag(tagType, name, open.start, close.end);
    }
  
negative.code:   
    final RegExp _validIdentifier = new RegExp(r'^[0-9a-zA-Z\_\-\.]+$');
    
    static const _tagTypeMap = const {
            '#': TagType.openSection,
            '^': TagType.openInverseSection,
            '/': TagType.closeSection,
            '&': TagType.unescapedVariable,
            '>': TagType.partial,
            '!': TagType.comment};
    
    //TODO clean up EOF handling.
    Tag _readTag() {
      
      var open = _expect(TokenType.openDelimiter);
      
      _readIf(TokenType.whitespace);
      
      // A sigil is the character which identifies which sort of tag it is,
      // i.e.  '#', '/', or '>'.
      // Variable tags and triple mustache tags don't have a sigil.
      TagType tagType;
      
      if (open.value == '{{{') {
        tagType = TagType.tripleMustache;
      } else {
        var sigil = _readIf(TokenType.sigil);
        tagType = sigil == null ? TagType.variable : _tagTypeMap[sigil.value];
      }
        
      _readIf(TokenType.whitespace);
      
      // TODO split up names here instead of during render.
      // Also check that they are valid token types.
  