@Override
   public void parse(IRtfSource source, IRtfListener listener) throws IOException
   {
      this.source = source;
      this.listener = listener;
      groupDepth = 0;
      parsingHex = false;
      buffer = new ByteBuffer();

      listener.processDocumentStart();

      int ch;
      parsingHex = false;

      while (true)
      {

         ch = source.read();
         if (ch == -1)
         {
            break;
         }

         if (groupDepth < 0)
         {
            throw new IllegalStateException("Group stack underflow");
         }

         switch (ch)
         {
            case '{':
            {
               handleGroupStart();
               break;
            }

            case '}':
            {
               handleGroupEnd();
               break;
            }

            case '\\':
            {
               handleCommand();
               break;
            }

            case '\r':
            case '\n':
            {
               break;
            }

            case '\t':
            {
               handleCharacterData();
               listener.processCommand(Command.tab, 0, false, false);
               break;
            }

            default:
            {
               handleCharacterByte(ch);
               break;
            }
         }
      }

      if (groupDepth < 0)
      {
         throw new IllegalStateException("Group stack underflow");
      }

      if (groupDepth > 0)
      {
         throw new IllegalStateException("Unmatched brace");
      }

      listener.processDocumentEnd();
   }