private ThreeElementMatchResult matchNext3Children(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;
  }
private ThreeElementMatchResult matchNext3Children(OT[] oldChildren, NT[] newChildren, int oldIndex, int newIndex, int oldLimit, int newLimit)