@NotNull
  public static Map<MethodSignature, CandidateInfo> getMapToOverrideImplement(PsiClass aClass,
                                                                              Collection<? extends HierarchicalMethodSignature> allMethodSignatures,
                                                                              boolean toImplement,
                                                                              boolean skipImplemented) {
    Map<MethodSignature, PsiMethod> abstracts = new LinkedHashMap<>();
    Map<MethodSignature, PsiMethod> finals = new LinkedHashMap<>();
    Map<MethodSignature, PsiMethod> concretes = new LinkedHashMap<>();

    PsiUtilCore.ensureValid(aClass);
    for (HierarchicalMethodSignature signature : allMethodSignatures) {
      PsiMethod method = signature.getMethod();
      if (method instanceof GrTraitMethod) {
        for (HierarchicalMethodSignature superSignature : signature.getSuperSignatures()) {
          processMethod(aClass, skipImplemented, abstracts, finals, concretes, superSignature, superSignature.getMethod());
        }
      }
      else {
        processMethod(aClass, skipImplemented, abstracts, finals, concretes, signature, method);
      }
    }

    final Map<MethodSignature, CandidateInfo> result = new TreeMap<>(new OverrideImplementExploreUtil.MethodSignatureComparator());
    if (toImplement || aClass.isInterface()) {
      collectMethodsToImplement(aClass, abstracts, finals, concretes, result);
    }
    else {
      for (Map.Entry<MethodSignature, PsiMethod> entry : concretes.entrySet()) {
        MethodSignature signature = entry.getKey();
        PsiMethod concrete = entry.getValue();
        if (finals.get(signature) == null) {
          PsiMethod abstractOne = abstracts.get(signature);
          if (abstractOne == null || !abstractOne.getContainingClass().isInheritor(concrete.getContainingClass(), true) ||
              CommonClassNames.JAVA_LANG_OBJECT.equals(concrete.getContainingClass().getQualifiedName())) {
            PsiSubstitutor subst = OverrideImplementExploreUtil.correctSubstitutor(concrete, signature.getSubstitutor());
            CandidateInfo info = new CandidateInfo(concrete, subst);
            result.put(signature, info);
          }
        }
      }
    }

    return result;
  }
@NotNull
  public static Map<MethodSignature, CandidateInfo> getMapToOverrideImplement(PsiClass aClass,
                                                                              Collection<? extends HierarchicalMethodSignature> allMethodSignatures,
                                                                              boolean toImplement,
                                                                              boolean skipImplemented)