private static PsiClass @NotNull [] calculateDirectSubClasses(@NotNull Project project,
                                                                @NotNull PsiClass baseClass,
                                                                @NotNull String baseClassName,
                                                                @NotNull DirectClassInheritorsSearch.SearchParameters parameters) {
    SearchScope useScope;
    CompilerDirectHierarchyInfo info = performSearchUsingCompilerIndices(parameters, project);
    useScope = ReadAction.compute(() -> {
      SearchScope resultScope = PsiSearchHelper.getInstance(project).getUseScope(baseClass);
      if (info == null) return resultScope;
      return resultScope.intersectWith(info.getDirtyScope());
    });

    DumbService dumbService = DumbService.getInstance(project);
    GlobalSearchScope globalUseScope = ReadAction.compute(
      () -> new JavaSourceFilterScope(GlobalSearchScopeUtil.toGlobalSearchScope(useScope, project)));
    Collection<PsiReferenceList> candidates =
      dumbService.runReadActionInSmartMode(() -> JavaSuperClassNameOccurenceIndex.getInstance().getOccurrences(baseClassName, project, globalUseScope));

    RelaxedDirectInheritorChecker checker = dumbService.runReadActionInSmartMode(() -> new RelaxedDirectInheritorChecker(baseClass));
    // memory/speed optimisation: it really is a map(string -> PsiClass or List<PsiClass>)
    final Map<String, Object> classesWithFqn = new HashMap<>();

    List<PsiAnonymousClass> anonymous = new ArrayList<>();

    processConcurrentlyIfTooMany(candidates,
       referenceList -> {
         ProgressManager.checkCanceled();
         dumbService.runReadActionInSmartMode(() -> {
           PsiElement parent = referenceList.getParent();
           PsiClass candidate;
           if (parent instanceof PsiClass && checker.checkInheritance(candidate = (PsiClass)parent)) {
             String fqn = candidate.getQualifiedName();

             synchronized (classesWithFqn) {
               if (candidate instanceof PsiAnonymousClass) {
                 anonymous.add((PsiAnonymousClass)candidate);
                 return;
               }

               Object value = classesWithFqn.get(fqn);
               if (value == null) {
                 classesWithFqn.put(fqn, candidate);
               }
               else if (value instanceof PsiClass) {
                 List<PsiClass> list = new ArrayList<>();
                 list.add((PsiClass)value);
                 list.add(candidate);
                 classesWithFqn.put(fqn, list);
               }
               else {
                 //noinspection unchecked
                 List<PsiClass> list = (List<PsiClass>)value;
                 list.add(candidate);
               }
             }
           }
         });

         return true;
       });

    final List<PsiClass> result = new ArrayList<>();
    synchronized (classesWithFqn) {
      for (Object value : classesWithFqn.values()) {
        if (value instanceof PsiClass) {
          result.add((PsiClass)value);
        }
        else {
          //noinspection unchecked
          List<PsiClass> list = (List<PsiClass>)value;
          result.addAll(list);
        }
      }
    }

    Collection<PsiAnonymousClass> anonymousCandidates =
      dumbService.runReadActionInSmartMode(() -> JavaAnonymousClassBaseRefOccurenceIndex.getInstance()
        .getOccurences(baseClassName, project, globalUseScope));

    processConcurrentlyIfTooMany(anonymousCandidates, candidate-> {
      if (dumbService.runReadActionInSmartMode(() -> checker.checkInheritance(candidate))) {
        synchronized (result) {
          anonymous.add(candidate);
        }
      }
      return true;
    });

    boolean isEnum = ReadAction.compute(baseClass::isEnum);
    if (isEnum) {
      // abstract enum can be subclassed in the body
      PsiField[] fields = ReadAction.compute(baseClass::getFields);
      for (final PsiField field : fields) {
        ProgressManager.checkCanceled();
        if (field instanceof PsiEnumConstant) {
          PsiEnumConstantInitializer initializingClass =
            ReadAction.compute(((PsiEnumConstant)field)::getInitializingClass);
          if (initializingClass != null) {
            synchronized (result) {
              anonymous.add(initializingClass); // it surely is an inheritor
            }
          }
        }
      }
    }

    if (info != null) {
      info.getHierarchyChildren().forEach(aClass -> {
        if (aClass instanceof PsiAnonymousClass) {
          anonymous.add((PsiAnonymousClass)aClass);
        }
        else if (aClass instanceof PsiClass) {
          result.add((PsiClass)aClass);
        }
      });
    }

    synchronized (result) {
      if (result.isEmpty() && anonymous.isEmpty()) return PsiClass.EMPTY_ARRAY;

      result.addAll(anonymous);
      return result.toArray(PsiClass.EMPTY_ARRAY);
    }
  }
private static PsiClass @NotNull [] calculateDirectSubClasses(@NotNull Project project,
                                                                @NotNull PsiClass baseClass,
                                                                @NotNull String baseClassName,
                                                                @NotNull DirectClassInheritorsSearch.SearchParameters parameters)