private void finishLine(NodeList body) {
      NodeList result = closeRemainingTags();
      if (result == null) return;

      state = State.None;
      body.add(result);
    }
    public AstNode visit(Whitespace ws) {
      if (!ws.getHasNewline()) return ws;

      NodeList result = closeRemainingTags();
      if (result == null) return ws;

      state = State.None;
      result.add(ws);
      return result;
    }
 private NodeList closeRemainingTags() {
   NodeList result = null;
   switch (state) {
     case Italics:
       result = new NodeList();
       result.add(ITALICS.createClose(true));
       break;
     case Bold:
       result = new NodeList();
       result.add(BOLD.createClose(true));
       break;
     case BoldItalics:
       result = new NodeList();
       result.add(ITALICS.createClose(true));
       result.add(BOLD.createClose(true));
       break;
     case ItalicsBold:
       result = new NodeList();
       result.add(BOLD.createClose(true));
       result.add(ITALICS.createClose(true));
       break;
   }
   return result;
 }
    private void toTag(LineEntry entry, NodeList result) {
      switch (entry.tickCount) {
        case 2:
          switch (state) {
            case Italics:
              result.add(ITALICS.createClose(false));
              state = State.None;
              break;
            case BoldItalics:
              result.add(ITALICS.createClose(false));
              state = State.Bold;
              break;
            case ItalicsBold:
              result.add(BOLD.createClose(true));
              result.add(ITALICS.createClose(false));
              result.add(BOLD.createOpen(true));
              state = State.Bold;
              break;
            case Bold:
              result.add(ITALICS.createOpen(false));
              state = State.BoldItalics;
              break;
            case None:
              result.add(ITALICS.createOpen(false));
              state = State.Italics;
              break;
          }
          break;

        case 3:
          switch (state) {
            case Bold:
              result.add(BOLD.createClose(false));
              state = State.None;
              break;
            case BoldItalics:
              result.add(ITALICS.createClose(true));
              result.add(BOLD.createClose(false));
              result.add(ITALICS.createOpen(true));
              state = State.Italics;
              break;
            case ItalicsBold:
              result.add(BOLD.createClose(false));
              state = State.Italics;
              break;
            case Italics:
              result.add(BOLD.createOpen(false));
              state = State.ItalicsBold;
              break;
            case None:
              result.add(BOLD.createOpen(false));
              state = State.Bold;
              break;
          }
          break;

        case 5:
          switch (state) {
            case Italics:
              result.add(ITALICS.createClose(false));
              result.add(BOLD.createOpen(false));
              state = State.Bold;
              break;
            case Bold:
              result.add(BOLD.createClose(false));
              result.add(ITALICS.createOpen(false));
              state = State.Italics;
              break;
            case BoldItalics:
              result.add(ITALICS.createClose(false));
              result.add(BOLD.createClose(false));
              state = State.None;
              break;
            case ItalicsBold:
              result.add(BOLD.createClose(false));
              result.add(ITALICS.createClose(false));
              state = State.None;
              break;
            case None:
              result.add(ITALICS.createOpen(false));
              result.add(BOLD.createOpen(false));
              state = State.ItalicsBold;
              break;
          }
          break;
      }
    }