private Match classesMatch(PsiAnonymousClass class1, PsiAnonymousClass class2) {
    markDeclarationsAsEquivalent(class1, class2);
    PsiJavaCodeReferenceElement baseClass1 = class1.getBaseClassReference();
    PsiJavaCodeReferenceElement baseClass2 = class2.getBaseClassReference();
    Match match = javaCodeReferenceElementsMatch(baseClass1, baseClass2);
    if (!match.isExactMatch()) return EXACT_MISMATCH;
    List<PsiMember> children1 = PsiTreeUtil.getChildrenOfTypeAsList(class1, PsiMember.class);
    List<PsiMember> children2 = PsiTreeUtil.getChildrenOfTypeAsList(class2, PsiMember.class);
    int size = children1.size();
    if (size != children2.size()) return EXACT_MISMATCH;
    children1 = ContainerUtil.sorted(children1, MEMBER_COMPARATOR);
    children2 = ContainerUtil.sorted(children2, MEMBER_COMPARATOR);
    for (int i = 0; i < size; i++) {
      // first pass checks only signatures for accurate reference tracking
      PsiElement child1 = children1.get(i);
      PsiElement child2 = children2.get(i);
      if (child1 instanceof PsiMethod && child2 instanceof PsiMethod) {
        if (!methodSignaturesMatch((PsiMethod)child1, (PsiMethod)child2)) {
          return EXACT_MISMATCH;
        }
      } else if (child1 instanceof PsiField && child2 instanceof PsiField) {
        if (!variableSignatureMatch((PsiField)child1, (PsiField)child2)) {
          return EXACT_MISMATCH;
        }
      }
    }
    for (int i = 0; i < size; i++) {
      PsiElement child1 = children1.get(i);
      PsiElement child2 = children2.get(i);
      if (child1 instanceof PsiMethod && child2 instanceof PsiMethod) {
        // method signature already checked
        if (!codeBlocksAreEquivalent(((PsiMethod)child1).getBody(), ((PsiMethod)child2).getBody())) return EXACT_MISMATCH;
      } else if (child1 instanceof PsiField && child2 instanceof PsiField) {
        // field signature already checked
        if (!expressionsAreEquivalent(((PsiField)child1).getInitializer(), ((PsiField)child2).getInitializer())) return EXACT_MISMATCH;
      } else if (child1 instanceof PsiClassInitializer && child2 instanceof PsiClassInitializer) {
        if (!classInitializersMatch((PsiClassInitializer)child1, (PsiClassInitializer)child2).isExactMatch()) return EXACT_MISMATCH;
      } else if (!PsiEquivalenceUtil.areElementsEquivalent(child1, child2)) {
        return EXACT_MISMATCH;
      }
    }
    return EXACT_MATCH;
  }
private Match classesMatch(PsiAnonymousClass class1, PsiAnonymousClass class2)