void (TextRange range, @Nullable SplitHunk splitHunk, final MyAppliedData value, @NotNull IntPair contextOffsetInPatchSteps) { // cut last lines but not the very first final List<String> list = value.getList(); //last line should be taken from includeConsumer even it seems to be equal with base context line( they can differ with line separator) boolean eofHunkAndLastLineShouldBeChanged = containsLastLine(range) && splitHunk != null && splitHunk.getContextAfter().isEmpty() && !splitHunk.getAfterAll().isEmpty(); int cnt = list.size() - 1; int i = range.getEndOffset(); if (!eofHunkAndLastLineShouldBeChanged) { for (; i > range.getStartOffset() && cnt >= 0; i--, cnt--) { if (!list.get(cnt).equals(myLines.get(i))) { break; } } } int endSize = list.size(); if (cnt + 1 <= list.size() - 1) { endSize = cnt + 1; } int cntStart = 0; int j = range.getStartOffset(); if (endSize > 0) { int lastProcessedIndex = eofHunkAndLastLineShouldBeChanged ? list.size() - 1 : list.size(); for (; j < range.getEndOffset() && cntStart < lastProcessedIndex; j++, cntStart++) { if (!list.get(cntStart).equals(myLines.get(j))) { break; } } } if (j != range.getStartOffset() || i != range.getEndOffset()) { if (cntStart >= endSize) { // +1 since we set end index inclusively if (list.size() == (range.getLength() + 1)) { // for already applied myHadAlreadyAppliedMet = value.isHaveAlreadyApplied(); processAppliedInfo(splitHunk, range, contextOffsetInPatchSteps, AppliedTextPatch.HunkStatus.ALREADY_APPLIED); } else { // deletion final UnfairTextRange textRange = new UnfairTextRange(j, i + (cntStart - endSize)); myTransformations.put(textRange, new MyAppliedData(Collections.emptyList(), value.isHaveAlreadyApplied(), value.isPlaceCoincide(), value.isChangedCoincide(), value.myChangeType)); processAppliedInfo(splitHunk, range, contextOffsetInPatchSteps, AppliedTextPatch.HunkStatus.EXACTLY_APPLIED); } } else { if (i < j) { // insert case // just took one line assert cntStart > 0; final MyAppliedData newData = new MyAppliedData(new ArrayList<>(list.subList(cntStart - (j - i), endSize)), value.isHaveAlreadyApplied(), value.isPlaceCoincide(), value.isChangedCoincide(), value.myChangeType); final TextRange newRange = new TextRange(i, i); myTransformations.put(newRange, newData); processAppliedInfo(splitHunk, range, contextOffsetInPatchSteps, AppliedTextPatch.HunkStatus.EXACTLY_APPLIED); return; } final MyAppliedData newData = new MyAppliedData(new ArrayList<>(list.subList(cntStart, endSize)), value.isHaveAlreadyApplied(), value.isPlaceCoincide(), value.isChangedCoincide(), value.myChangeType); final TextRange newRange = new TextRange(j, i); myTransformations.put(newRange, newData); processAppliedInfo(splitHunk, range, contextOffsetInPatchSteps, AppliedTextPatch.HunkStatus.EXACTLY_APPLIED); } } else { myTransformations.put(range, value); processAppliedInfo(splitHunk, range, contextOffsetInPatchSteps, AppliedTextPatch.HunkStatus.EXACTLY_APPLIED); } }