boolean (@NotNull PsiElement element1, @NotNull PsiElement element2, @NotNull BiPredicate<? super PsiReference, ? super PsiReference> refsAreEqual, @Nullable BiPredicate<? super PsiElement, ? super PsiElement> leafsAreEqual, @Nullable Predicate<? super PsiElement> isElementSignificantCondition, boolean areCommentsSignificant) { if (element1 == element2) return true; ASTNode node1 = element1.getNode(); ASTNode node2 = element2.getNode(); if (node1 == null || node2 == null) return false; if (node1.getElementType() != node2.getElementType()) return false; PsiElement[] children1 = getFilteredChildren(element1, isElementSignificantCondition, areCommentsSignificant); PsiElement[] children2 = getFilteredChildren(element2, isElementSignificantCondition, areCommentsSignificant); if (children1.length != children2.length) return false; for (int i = 0; i < children1.length; i++) { PsiElement child1 = children1[i]; PsiElement child2 = children2[i]; if (!areEquivalent(child1, child2, refsAreEqual, leafsAreEqual, isElementSignificantCondition, areCommentsSignificant)) { return false; } } if (children1.length == 0) { if (leafsAreEqual != null) { if (!leafsAreEqual.test(element1, element2)) return false; } else { if (!element1.textMatches(element2)) return false; } } PsiReference ref1 = element1.getReference(); if (ref1 != null) { PsiReference ref2 = element2.getReference(); if (ref2 == null) return false; if (!refsAreEqual.test(ref1, ref2)) return false; } return true; }