List<PatchHunk> (@NotNull String beforeContent, @NotNull String afterContent, int contextLineCount) { if (beforeContent.equals(afterContent)) return Collections.emptyList(); if (beforeContent.isEmpty()) { return singletonList(createWholeFileHunk(afterContent, true, true)); } if (afterContent.isEmpty()) { return singletonList(createWholeFileHunk(beforeContent, false, true)); } List<PatchHunk> hunks = new ArrayList<>(); List<String> beforeLines = tokenize(beforeContent); List<String> afterLines = tokenize(afterContent); boolean beforeNoNewlineAtEOF = !beforeContent.endsWith("\n"); boolean afterNoNewlineAtEOF = !afterContent.endsWith("\n"); List<Range> fragments = compareLines(beforeLines, afterLines, beforeNoNewlineAtEOF, afterNoNewlineAtEOF); int hunkStart = 0; while (hunkStart < fragments.size()) { List<Range> hunkFragments = getAdjacentFragments(fragments, hunkStart, contextLineCount); hunks.add(createHunk(hunkFragments, beforeLines, afterLines, beforeNoNewlineAtEOF, afterNoNewlineAtEOF, contextLineCount)); hunkStart += hunkFragments.size(); } return hunks; }