List<MergeRange> (@NotNull List<? extends Line> lines1, @NotNull List<? extends Line> lines2, @NotNull List<? extends Line> lines3, @NotNull ComparisonPolicy policy, @NotNull CancellationChecker indicator, boolean keepIgnoredChanges) { indicator.checkCanceled(); List<Line> iwLines1 = convertMode(lines1, IGNORE_WHITESPACES); List<Line> iwLines2 = convertMode(lines2, IGNORE_WHITESPACES); List<Line> iwLines3 = convertMode(lines3, IGNORE_WHITESPACES); FairDiffIterable iwChanges1 = compareSmart(iwLines2, iwLines1, indicator); iwChanges1 = optimizeLineChunks(lines2, lines1, iwChanges1, indicator); FairDiffIterable iterable1 = correctChangesSecondStep(lines2, lines1, iwChanges1); FairDiffIterable iwChanges2 = compareSmart(iwLines2, iwLines3, indicator); iwChanges2 = optimizeLineChunks(lines2, lines3, iwChanges2, indicator); FairDiffIterable iterable2 = correctChangesSecondStep(lines2, lines3, iwChanges2); if (keepIgnoredChanges && policy != DEFAULT) { return ComparisonMergeUtil.buildMerge(iterable1, iterable2, (index1, index2, index3) -> equalsDefaultPolicy(lines1, lines2, lines3, index1, index2, index3), indicator); } else { return ComparisonMergeUtil.buildSimple(iterable1, iterable2, indicator); } }