List<InnerChange> (@NotNull String currentContent, @NotNull String contentAfter, @NotNull List<InnerChange> changes) { if (contentAfter.equals(currentContent)) return changes; List<DiffFragment> delta = ByWord.compare(contentAfter, currentContent, ComparisonPolicy.DEFAULT, DumbProgressIndicator.INSTANCE); DiffIterable iterable = DiffIterableUtil.createFragments(delta, contentAfter.length(), currentContent.length()); LineNumberConvertor convertor = LineNumberConvertor.fromIterable(iterable); return ContainerUtil.map(changes, change -> { int start = convertor.convertApproximate(change.startOffset); int end = convertor.convertApproximate(change.endOffset); return new InnerChange(start, end, change.type); }); }