public synchronized void documentChanged(DocumentEvent event) {
      if (!enabled) return;

      String text = event.getText();

      if (text.equals(COMMAND_TERMINATOR)) {
        if (buffer.length() > 0) { // If we just get a new-line token, execute the current 'thing'.
          buffer.append(COMMAND_TERMINATOR);
          String command = buffer.toString();
          reset();

          console.revertAndAppend(command);
        } else { // If there is no current 'thing', just execute the command terminator ('\n', '\r'
                 // or '\r\n') command.
          queue(COMMAND_TERMINATOR, console.getInputOffset());
          execute();
        }
        return;
      }

      int offset = event.getOffset();
      int length = event.getLength();

      int start = offset - console.getInputOffset();
      if (start >= 0) {
        buffer.replace(start, start + length, text);

        int commandStartOffset = console.getInputOffset();

        String rest = buffer.toString();
        boolean commandsQueued = false;
        do {
          int index = rest.indexOf(COMMAND_TERMINATOR);
          if (index == -1) {
            reset();
            buffer.append(rest);
            break;
          }

          String command = rest.substring(0, index);

          queue(command, commandStartOffset);
          commandStartOffset += index;
          commandsQueued = true;

          rest = rest.substring(index + COMMAND_TERMINATOR.length());
        } while (true);

        if (commandsQueued) execute();
      } else {
        buffer.insert(0, text);
        String toAppend = buffer.toString();
        reset();
        console.revertAndAppend(toAppend);
      }
    }