/**
  * Constructs a plain text document. A default root element is created, and the tab size set to 5.
  *
  * @param tmf The <code>TokenMakerFactory</code> for this document. If this is <code>null</code>,
  *     a default factory is used.
  * @param syntaxStyle The syntax highlighting scheme to use.
  */
 public RSyntaxDocument(TokenMakerFactory tmf, String syntaxStyle) {
   super(new RGapContent());
   putProperty(tabSizeAttribute, new Integer(5));
   lastTokensOnLines = new DynamicIntArray(400);
   lastTokensOnLines.add(Token.NULL); // Initial (empty) line.
   s = new Segment();
   setTokenMakerFactory(tmf);
   setSyntaxStyle(syntaxStyle);
 }
  /**
   * Alerts all listeners to this document of an insertion. This is overridden so we can update our
   * syntax highlighting stuff.
   *
   * <p>The syntax highlighting stuff has to be here instead of in <code>insertUpdate</code> because
   * <code>insertUpdate</code> is not called by the undo/redo actions, but this method is.
   *
   * @param e The change.
   */
  protected void fireInsertUpdate(DocumentEvent e) {

    /*
     * Now that the text is actually inserted into the content and
     * element structure, we can update our token elements and "last
     * tokens on lines" structure.
     */

    Element lineMap = getDefaultRootElement();
    DocumentEvent.ElementChange change = e.getChange(lineMap);
    Element[] added = change == null ? null : change.getChildrenAdded();

    int numLines = lineMap.getElementCount();
    int line = lineMap.getElementIndex(e.getOffset());
    int previousLine = line - 1;
    int previousTokenType = (previousLine > -1 ? lastTokensOnLines.get(previousLine) : Token.NULL);

    // If entire lines were added...
    if (added != null && added.length > 0) {

      Element[] removed = change.getChildrenRemoved();
      int numRemoved = removed != null ? removed.length : 0;

      int endBefore = line + added.length - numRemoved;
      // System.err.println("... adding lines: " + line + " - " + (endBefore-1));
      // System.err.println("... ... added: " + added.length + ", removed:" + numRemoved);
      for (int i = line; i < endBefore; i++) {

        setSharedSegment(i); // Loads line i's text into s.

        int tokenType = tokenMaker.getLastTokenTypeOnLine(s, previousTokenType);
        lastTokensOnLines.add(i, tokenType);
        // System.err.println("--------- lastTokensOnLines.size() == " +
        // lastTokensOnLines.getSize());

        previousTokenType = tokenType;
      } // End of for (int i=line; i<endBefore; i++).

      // Update last tokens for lines below until they stop changing.
      updateLastTokensBelow(endBefore, numLines, previousTokenType);

    } // End of if (added!=null && added.length>0).

    // Otherwise, text was inserted on a single line...
    else {

      // Update last tokens for lines below until they stop changing.
      updateLastTokensBelow(line, numLines, previousTokenType);
    } // End of else.

    // Let all listeners know about the insertion.
    super.fireInsertUpdate(e);
  }