Block (String @NotNull [] prevContent) { try { FairDiffIterable iterable = ByLine.compare(Arrays.asList(prevContent), Arrays.asList(mySource), ComparisonPolicy.IGNORE_WHITESPACES, DumbProgressIndicator.INSTANCE); // empty range should not be transferred to the non-empty range boolean greedy = myStart != myEnd; int start = myStart; int end = myEnd; int shift = 0; for (Range range : iterable.iterateChanges()) { int changeStart = range.start2 + shift; int changeEnd = range.end2 + shift; int changeShift = (range.end1 - range.start1) - (range.end2 - range.start2); DiffUtil.UpdatedLineRange updatedRange = DiffUtil.updateRangeOnModification(start, end, changeStart, changeEnd, changeShift, greedy); start = updatedRange.startLine; end = updatedRange.endLine; shift += changeShift; } if (start < 0 || end > prevContent.length || end < start) { LOG.error("Invalid block range: [" + start + ", " + end + "); length - " + prevContent.length); } // intern strings, reducing memory usage for (Range range : iterable.iterateUnchanged()) { int count = range.end1 - range.start1; for (int i = 0; i < count; i++) { int prevIndex = range.start1 + i; int sourceIndex = range.start2 + i; if (prevContent[prevIndex].equals(mySource[sourceIndex])) { prevContent[prevIndex] = mySource[sourceIndex]; } } } return new Block(prevContent, start, end); } catch (DiffTooBigException e) { return new Block(prevContent, 0, 0); } }