/**
   * Whenever an UndoableEdit happens the edit will either be absorbed by the current compound edit
   * or a new compound edit will be started
   */
  @Override
  public void undoableEditHappened(UndoableEditEvent e) {
    //  Start a new compound edit

    AbstractDocument.DefaultDocumentEvent docEvt = (DefaultDocumentEvent) e.getEdit();

    if (compoundEdit == null) {
      compoundEdit = startCompoundEdit(e.getEdit());
      startCombine = false;
      updateDirty();
      return;
    }

    int editLine = ((SyntaxDocument) docEvt.getDocument()).getLineNumberAt(docEvt.getOffset());

    //  Check for an incremental edit or backspace.
    //  The Change in Caret position and Document length should both be
    //  either 1 or -1.
    if ((startCombine || Math.abs(docEvt.getLength()) == 1) && editLine == lastLine) {
      compoundEdit.addEdit(e.getEdit());
      startCombine = false;
      updateDirty();
      return;
    }

    //  Not incremental edit, end previous edit and start a new one
    lastLine = editLine;

    compoundEdit.end();
    compoundEdit = startCompoundEdit(e.getEdit());

    updateDirty();
  }
    @Override
    public void undo() throws CannotUndoException {
      //  End the edit so future edits don't get absorbed by this edit

      if (compoundEdit != null) {
        compoundEdit.end();
      }

      super.undo();

      //  Always start a new compound edit after an undo

      compoundEdit = null;
    }
  /*
   **  Each CompoundEdit will store a group of related incremental edits
   **  (ie. each character typed or backspaced is an incremental edit)
   */
  private CompoundEdit startCompoundEdit(UndoableEdit anEdit) {
    //  Track Caret and Document information of this compound edit
    // AbstractDocument.DefaultDocumentEvent docEvt = (DefaultDocumentEvent) anEdit;

    //  The compound edit is used to store incremental edits

    compoundEdit = new MyCompoundEdit();
    compoundEdit.addEdit(anEdit);

    //  The compound edit is added to the UndoManager. All incremental
    //  edits stored in the compound edit will be undone/redone at once

    addEdit(compoundEdit);

    return compoundEdit;
  }