private static boolean processCachedMembersByName(@NotNull PsiClass aClass,
                                                    @NotNull PsiScopeProcessor processor,
                                                    @NotNull ResolveState state,
                                                    @Nullable Set<? super PsiClass> visited,
                                                    PsiElement last,
                                                    @NotNull PsiElement place,
                                                    boolean isRaw,
                                                    @NotNull PsiSubstitutor substitutor,
                                                    String name,
                                                    @NotNull LanguageLevel languageLevel,
                                                    @NotNull GlobalSearchScope resolveScope) {
    java.util.function.Function<PsiMember, PsiSubstitutor> finalSubstitutor = new java.util.function.Function<PsiMember, PsiSubstitutor>() {
      final ScopedClassHierarchy hierarchy = ScopedClassHierarchy.getHierarchy(aClass, resolveScope);
      final PsiElementFactory factory = JavaPsiFacade.getElementFactory(aClass.getProject());

      @Override
      public PsiSubstitutor apply(PsiMember member) {
        PsiSubstitutor finalSubstitutor = member.hasModifierProperty(PsiModifier.STATIC) ? substitutor : obtainSubstitutor(member);
        return member instanceof PsiMethod ? checkRaw(isRaw, factory, (PsiMethod)member, finalSubstitutor) : finalSubstitutor;
      }

      private PsiSubstitutor obtainSubstitutor(PsiMember member) {
        PsiClass containingClass = Objects.requireNonNull(member.getContainingClass());
        PsiSubstitutor superSubstitutor = ObjectUtils.notNull(hierarchy.getSuperMembersSubstitutor(containingClass, languageLevel),
                                                              PsiSubstitutor.EMPTY);
        return obtainFinalSubstitutor(containingClass, superSubstitutor, aClass, substitutor, factory, languageLevel);
      }
    };

    ElementClassHint classHint = processor.getHint(ElementClassHint.KEY);

    if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.FIELD)) {
      PsiField fieldByName = aClass.findFieldByName(name, false);
      if (fieldByName != null) {
        if (!skipInvalid(fieldByName)) {
          processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
          if (!processor.execute(fieldByName, state)) return false;
        }
      }
      else {
        List<PsiMember> list = getMap(aClass, resolveScope).calcMembersByName(MemberType.FIELD, name, aClass, place);
        if (!list.isEmpty()) {
          boolean resolved = false;
          for (PsiMember candidateField : list) {
            PsiClass containingClass = candidateField.getContainingClass();
            if (skipInvalid(candidateField)) {
              continue;
            }
            if (containingClass == null) {
              PsiElement parent = candidateField.getParent();
              LOG.error("No class for field " + candidateField.getName() + " of " + candidateField.getClass() +
                        ", parent " + parent + " of " + (parent == null ? null : parent.getClass()));
              continue;
            }

            processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
            if (!processor.execute(candidateField, state.put(PsiSubstitutor.KEY, finalSubstitutor.apply(candidateField)))) {
              resolved = true;
            }
          }
          if (resolved) return false;
        }
      }
    }
    if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.CLASS)) {
      if (last != null && last.getContext() == aClass) {
        if (last instanceof PsiClass) {
          if (!processor.execute(last, state)) return false;
        }
        // Parameters
        PsiTypeParameterList list = aClass.getTypeParameterList();
        if (list != null && !list.processDeclarations(processor, state, last, place)) return false;
      }
      if (!(last instanceof PsiReferenceList)) {
        PsiClass classByName = aClass.findInnerClassByName(name, false);
        if (classByName != null) {
          if (!skipInvalid(classByName)) {
            processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
            if (!processor.execute(classByName, state)) return false;
          }
        }
        else {
          List<PsiMember> list = getMap(aClass, resolveScope).calcMembersByName(MemberType.CLASS, name, aClass, place);
          if (!list.isEmpty()) {
            boolean resolved = false;
            for (PsiMember inner : list) {
              if (skipInvalid(inner)) continue;

              PsiClass containingClass = inner.getContainingClass();
              if (containingClass != null) {
                processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
                if (!processor.execute(inner, state.put(PsiSubstitutor.KEY, finalSubstitutor.apply(inner)))) {
                  resolved = true;
                }
              }
            }
            if (resolved) return false;
          }
        }
      }
    }
    if (classHint == null || classHint.shouldProcess(ElementClassHint.DeclarationKind.METHOD)) {
      if (processor instanceof MethodResolverProcessor) {
        MethodResolverProcessor methodResolverProcessor = (MethodResolverProcessor)processor;
        if (methodResolverProcessor.isConstructor()) {
          PsiMethod[] constructors = aClass.getConstructors();
          methodResolverProcessor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, aClass);
          for (PsiMethod constructor : constructors) {
            if (!skipInvalid(constructor) && !methodResolverProcessor.execute(constructor, state)) return false;
          }
          return true;
        }
      }
      List<PsiMember> list = getMap(aClass, resolveScope).calcMembersByName(MemberType.METHOD, name, aClass, place);
      if (!list.isEmpty()) {
        boolean resolved = false;
        for (PsiMember candidate : list) {
          ProgressIndicatorProvider.checkCanceled();
          PsiMethod candidateMethod = (PsiMethod)candidate;
          if (skipInvalid(candidateMethod)) continue;

          if (processor instanceof MethodResolverProcessor) {
            if (candidateMethod.isConstructor() != ((MethodResolverProcessor)processor).isConstructor()) continue;
          }
          PsiClass containingClass = candidateMethod.getContainingClass();
          if (containingClass == null || visited != null && visited.contains(containingClass)) {
            continue;
          }

          processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, containingClass);
          if (!processor.execute(candidateMethod, state.put(PsiSubstitutor.KEY, finalSubstitutor.apply(candidateMethod)))) {
            resolved = true;
          }
        }
        if (resolved) return false;

        if (visited != null) {
          for (PsiMember aList : list) {
            visited.add(aList.getContainingClass());
          }
        }
      }
    }
    return true;
  }
private static boolean processCachedMembersByName(@NotNull PsiClass aClass,
                                                    @NotNull PsiScopeProcessor processor,
                                                    @NotNull ResolveState state,
                                                    @Nullable Set<? super PsiClass> visited,
                                                    PsiElement last,
                                                    @NotNull PsiElement place,
                                                    boolean isRaw,
                                                    @NotNull PsiSubstitutor substitutor,
                                                    String name,
                                                    @NotNull LanguageLevel languageLevel,
                                                    @NotNull GlobalSearchScope resolveScope)