void () { if (myRanges.size() < 2) return; // nothing to do Range range1 = myRanges.get(myRanges.size() - 2); Range range2 = myRanges.get(myRanges.size() - 1); if (range1.end1 != range2.start1 && range1.end2 != range2.start2) { // if changes do not touch and we still can perform one of these optimisations, // it means that given DiffIterable is not LCS (because we can build a smaller one). This should not happen. return; } int count1 = range1.end1 - range1.start1; int count2 = range2.end1 - range2.start1; int equalForward = expandForward(myData1, myData2, range1.end1, range1.end2, range1.end1 + count2, range1.end2 + count2); int equalBackward = expandBackward(myData1, myData2, range2.start1 - count1, range2.start2 - count1, range2.start1, range2.start2); // nothing to do if (equalForward == 0 && equalBackward == 0) return; // merge chunks left [A]B[B] -> [AB]B if (equalForward == count2) { myRanges.remove(myRanges.size() - 1); myRanges.remove(myRanges.size() - 1); myRanges.add(new Range(range1.start1, range1.end1 + count2, range1.start2, range1.end2 + count2)); processLastRanges(); return; } // merge chunks right [A]A[B] -> A[AB] if (equalBackward == count1) { myRanges.remove(myRanges.size() - 1); myRanges.remove(myRanges.size() - 1); myRanges.add(new Range(range2.start1 - count1, range2.end1, range2.start2 - count1, range2.end2)); processLastRanges(); return; } Side touchSide = Side.fromLeft(range1.end1 == range2.start1); int shift = getShift(touchSide, equalForward, equalBackward, range1, range2); if (shift != 0) { myRanges.remove(myRanges.size() - 1); myRanges.remove(myRanges.size() - 1); myRanges.add(new Range(range1.start1, range1.end1 + shift, range1.start2, range1.end2 + shift)); myRanges.add(new Range(range2.start1 + shift, range2.end1, range2.start2 + shift, range2.end2)); } }