void read(Tokeniser t, CharacterReader r) {
      if (r.matchesLetter()) {
        String name = r.consumeLetterSequence();
        t.tagPending.appendTagName(name.toLowerCase());
        t.dataBuffer.append(name);
        return;
      }

      if (t.isAppropriateEndTagToken() && !r.isEmpty()) {
        char c = r.consume();
        switch (c) {
          case '\t':
          case '\n':
          case '\r':
          case '\f':
          case ' ':
            t.transition(BeforeAttributeName);
            break;
          case '/':
            t.transition(SelfClosingStartTag);
            break;
          case '>':
            t.emitTagPending();
            t.transition(Data);
            break;
          default:
            t.dataBuffer.append(c);
            anythingElse(t, r);
            break;
        }
      } else {
        anythingElse(t, r);
      }
    }
    void read(Tokeniser t, CharacterReader r) {
      if (r.matchesLetter()) {
        String name = r.consumeLetterSequence();
        t.dataBuffer.append(name.toLowerCase());
        t.emit(name);
        return;
      }

      char c = r.consume();
      switch (c) {
        case '\t':
        case '\n':
        case '\r':
        case '\f':
        case ' ':
        case '/':
        case '>':
          if (t.dataBuffer.toString().equals("script")) t.transition(ScriptDataEscaped);
          else t.transition(ScriptDataDoubleEscaped);
          t.emit(c);
          break;
        default:
          r.unconsume();
          t.transition(ScriptDataDoubleEscaped);
      }
    }
 void read(Tokeniser t, CharacterReader r) {
   if (r.matchesLetter()) {
     String name = r.consumeLetterSequence();
     t.doctypePending.name.append(name.toLowerCase());
     return;
   }
   char c = r.consume();
   switch (c) {
     case '>':
       t.emitDoctypePending();
       t.transition(Data);
       break;
     case '\t':
     case '\n':
     case '\r':
     case '\f':
     case ' ':
       t.transition(AfterDoctypeName);
       break;
     case nullChar:
       t.error(this);
       t.doctypePending.name.append(replacementChar);
       break;
     case eof:
       t.eofError(this);
       t.doctypePending.forceQuirks = true;
       t.emitDoctypePending();
       t.transition(Data);
       break;
     default:
       t.doctypePending.name.append(c);
   }
 }