@Override
    protected void changedUpdateImpl(@NotNull DocumentEvent e) {
      int oldOffset = intervalStart();
      RangeMarkerTree.RMNode<RangeMarkerEx> node = myNode;
      long newRange = isValid() && node != null ? applyChange(e, node.toScalarRange(), isGreedyToLeft(), isGreedyToRight(), isStickingToRight()) : -1;

      if (newRange != -1) {
        setRange(newRange);
        // Under certain conditions, when text is inserted at caret position, we position caret at the end of inserted text.
        // Ideally, client code should be responsible for positioning caret after document modification, but in case of
        // postponed formatting (after PSI modifications), this is hard to implement, so a heuristic below is used.
        if (e.getOldLength() == 0 && oldOffset == e.getOffset() &&
            !Boolean.TRUE.equals(myEditor.getUserData(EditorImpl.DISABLE_CARET_SHIFT_ON_WHITESPACE_INSERTION)) &&
            needToShiftWhiteSpaces(e)) {
          int afterInserted = e.getOffset() + e.getNewLength();
          setRange(TextRangeScalarUtil.toScalarRange(afterInserted, afterInserted));
        }
        int offset = intervalStart();
        if (DocumentUtil.isInsideSurrogatePair(getDocument(), offset)) {
          setRange(TextRangeScalarUtil.toScalarRange(offset - 1, offset - 1));
        }
      }
      else {
        setValid(true);
        int newOffset = Math.min(getStartOffset(), e.getOffset() + e.getNewLength());
        if (!e.getDocument().isInBulkUpdate() && e.isWholeTextReplaced()) {
          try {
            int line = ((DocumentEventImpl)e).translateLineViaDiff(myLogicalCaret.line);
            newOffset = myEditor.logicalPositionToOffset(new LogicalPosition(line, myLogicalCaret.column));
          }
          catch (FilesTooBigForDiffException ex) {
            LOG.info(ex);
          }
        }
        newOffset = DocumentUtil.alignToCodePointBoundary(getDocument(), newOffset);
        setRange(TextRangeScalarUtil.toScalarRange(newOffset, newOffset));
      }
      myLogicalColumnAdjustment = 0;
      myVisualColumnAdjustment = 0;
      if (oldOffset >= e.getOffset() && oldOffset <= e.getOffset() + e.getOldLength() && e.getNewLength() == 0 && e.getOldLength() > 0) {
        int inlaysToTheLeft = myEditor.getInlayModel().getInlineElementsInRange(e.getOffset(), e.getOffset()).size();
        boolean hasInlaysToTheRight = myEditor.getInlayModel().hasInlineElementAt(e.getOffset() + e.getOldLength());
        if (inlaysToTheLeft > 0 || hasInlaysToTheRight) {
          myLeansTowardsLargerOffsets = !hasInlaysToTheRight;
          myVisualColumnAdjustment = hasInlaysToTheRight ? inlaysToTheLeft : 0;
        }
        else if (oldOffset == e.getOffset()) {
          myLeansTowardsLargerOffsets = false;
        }
      }
    }
@Override
    protected void changedUpdateImpl(@NotNull DocumentEvent e)