PatchHunk (@NotNull List<? extends Range> hunkFragments, @NotNull List<String> beforeLines, @NotNull List<String> afterLines, boolean beforeNoNewlineAtEOF, boolean afterNoNewlineAtEOF, int contextLineCount) { Range first = hunkFragments.get(0); Range last = hunkFragments.get(hunkFragments.size() - 1); int contextStart1 = Math.max(first.start1 - contextLineCount, 0); int contextStart2 = Math.max(first.start2 - contextLineCount, 0); int contextEnd1 = Math.min(last.end1 + contextLineCount, beforeLines.size()); int contextEnd2 = Math.min(last.end2 + contextLineCount, afterLines.size()); PatchHunk hunk = new PatchHunk(contextStart1, contextEnd1, contextStart2, contextEnd2); int lastLine1 = contextStart1; int lastLine2 = contextStart2; for (Range fragment : hunkFragments) { int start1 = fragment.start1; int start2 = fragment.start2; int end1 = fragment.end1; int end2 = fragment.end2; assert start1 - lastLine1 == start2 - lastLine2; for (int i = lastLine1; i < start1; i++) { addLineToHunk(hunk, beforeLines, PatchLine.Type.CONTEXT, i, beforeNoNewlineAtEOF); } for (int i = start1; i < end1; i++) { addLineToHunk(hunk, beforeLines, PatchLine.Type.REMOVE, i, beforeNoNewlineAtEOF); } for (int i = start2; i < end2; i++) { addLineToHunk(hunk, afterLines, PatchLine.Type.ADD, i, afterNoNewlineAtEOF); } lastLine1 = end1; lastLine2 = end2; } assert contextEnd1 - lastLine1 == contextEnd2 - lastLine2; for (int i = lastLine1; i < contextEnd1; i++) { addLineToHunk(hunk, beforeLines, PatchLine.Type.CONTEXT, i, beforeNoNewlineAtEOF); } return hunk; }