void (@NotNull DocumentEvent e) { if (isDisposed()) return; enterBulkChangeUpdateBlock(); if (getChangesCount() == 0) return; LineRange lineRange = DiffUtil.getAffectedLineRange(e); int shift = DiffUtil.countLinesShift(e); List<S> corruptedStates = new SmartList<>(); for (int index = 0; index < getChangesCount(); index++) { S oldState = processDocumentChange(index, lineRange.start, lineRange.end, shift); if (oldState == null) continue; invalidateHighlighters(index); if (!isInsideCommand()) corruptedStates.add(oldState); } if (myUndoManager != null && !corruptedStates.isEmpty()) { // document undo is registered inside onDocumentChange, so our undo() will be called after its undo(). // thus thus we can avoid checks for isUndoInProgress() (to avoid modification of the same TextMergeChange by this listener) myUndoManager.undoableActionPerformed(new MyUndoableAction(MergeModelBase.this, corruptedStates, true)); } }