ThreeElementMatchResult (OT[] oldChildren, NT[] newChildren, int oldIndex, int newIndex, int oldLimit, int newLimit) { if (oldIndex >= oldLimit) return ThreeElementMatchResult.SKIP_NEW_1; if (newIndex >= newLimit) return ThreeElementMatchResult.SKIP_OLD_1; OT oldChild1 = oldChildren[oldIndex]; NT newChild1 = newChildren[newIndex]; CompareResult c11 = looksEqual(oldChild1, newChild1); if (c11 == CompareResult.EQUAL) return ThreeElementMatchResult.FULL_START_MATCH; if (c11 == CompareResult.DRILL_DOWN_NEEDED) return ThreeElementMatchResult.DRILL_DOWN_START_MATCH; OT oldChild2 = oldIndex < oldLimit - 1 ? oldChildren[oldIndex + 1] : null; NT newChild2 = newIndex < newLimit - 1 ? newChildren[newIndex + 1] : null; CompareResult c12 = looksEqual(oldChild1, newChild2); if (c12 == CompareResult.EQUAL || c12 == CompareResult.DRILL_DOWN_NEEDED) return ThreeElementMatchResult.SKIP_NEW_1; CompareResult c21 = looksEqual(oldChild2, newChild1); if (c21 == CompareResult.EQUAL || c21 == CompareResult.DRILL_DOWN_NEEDED) return ThreeElementMatchResult.SKIP_OLD_1; if (c11 == CompareResult.TYPE_ONLY) return ThreeElementMatchResult.REPLACE_START; if (c12 == CompareResult.TYPE_ONLY) return ThreeElementMatchResult.SKIP_NEW_1; if (c21 == CompareResult.TYPE_ONLY) return ThreeElementMatchResult.SKIP_OLD_1; // check whether two children are inserted/deleted // (which frequently is a case when e.g. a PsiMethod inserted, the trailing PsiWhiteSpace is appended too) OT oldChild3 = oldIndex < oldLimit - 2 ? oldChildren[oldIndex + 2] : null; NT newChild3 = newIndex < newLimit - 2 ? newChildren[newIndex + 2] : null; if (looksEqual(oldChild1, newChild3) != CompareResult.NOT_EQUAL) return ThreeElementMatchResult.SKIP_NEW_2; if (looksEqual(oldChild3, newChild1) != CompareResult.NOT_EQUAL) return ThreeElementMatchResult.SKIP_OLD_2; return ThreeElementMatchResult.NO_MATCH; }