static long applyChange(@NotNull DocumentEvent e, long range,
                          boolean isGreedyToLeft, boolean isGreedyToRight, boolean isStickingToRight) {
    int intervalStart = TextRangeScalarUtil.startOffset(range);
    int intervalEnd = TextRangeScalarUtil.endOffset(range);
    if (intervalStart == intervalEnd) {
      return processIfOnePoint(e, intervalStart, isGreedyToRight, isStickingToRight);
    }

    int offset = e.getOffset();
    int oldLength = e.getOldLength();
    int newLength = e.getNewLength();

    // changes after the end.
    if (offset > intervalEnd) {
      return TextRangeScalarUtil.toScalarRange(intervalStart, intervalEnd);
    }
    if (!isGreedyToRight && intervalEnd == offset) {
      // handle replaceString that was minimized and resulted in insertString at the range end
      if (e instanceof DocumentEventImpl && oldLength == 0 && ((DocumentEventImpl)e).getInitialStartOffset() < offset) {
        return TextRangeScalarUtil.toScalarRange(intervalStart, intervalEnd + newLength);
      }
      return TextRangeScalarUtil.toScalarRange(intervalStart, intervalEnd);
    }

    // changes before start
    if (intervalStart > offset + oldLength) {
      return TextRangeScalarUtil.toScalarRange(intervalStart + newLength - oldLength, intervalEnd + newLength - oldLength);
    }
    if (!isGreedyToLeft && intervalStart == offset + oldLength) {
      // handle replaceString that was minimized and resulted in insertString at the range start
      if (e instanceof DocumentEventImpl && oldLength == 0 && ((DocumentEventImpl)e).getInitialStartOffset() + ((DocumentEventImpl)e).getInitialOldLength() > offset) {
        return TextRangeScalarUtil.toScalarRange(intervalStart, intervalEnd + newLength);
      }
      return TextRangeScalarUtil.toScalarRange(intervalStart + newLength - oldLength, intervalEnd + newLength - oldLength);
    }

    // Changes inside marker's area. Expand/collapse.
    if (intervalStart <= offset && intervalEnd >= offset + oldLength) {
      return TextRangeScalarUtil.toScalarRange(intervalStart, intervalEnd + newLength - oldLength);
    }

    // At this point we either have (myStart xor myEnd inside changed area) or whole area changed.

    // Replacing prefix or suffix...
    if (intervalStart >= offset && intervalStart <= offset + oldLength && intervalEnd > offset + oldLength) {
      return TextRangeScalarUtil.toScalarRange(offset + newLength, intervalEnd + newLength - oldLength);
    }

    if (intervalEnd <= offset + oldLength && intervalStart < offset) {
      return TextRangeScalarUtil.toScalarRange(intervalStart, offset);
    }

    return -1;
  }
static long applyChange(@NotNull DocumentEvent e, long range,
                          boolean isGreedyToLeft, boolean isGreedyToRight, boolean isStickingToRight)