public static boolean areEquivalent(@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;
  }
public static boolean areEquivalent(@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)