@Override
    public CompilerRef.CompilerClassHierarchyElementDef @Nullable("return null if the class hierarchy contains ambiguous qualified names") [] getHierarchy(CompilerRef.CompilerClassHierarchyElementDef hierarchyElement,
                                                                                                                                                           boolean checkBaseClassAmbiguity,
                                                                                                                                                           boolean includeAnonymous,
                                                                                                                                                           int interruptNumber) {
      try {
        List<DirectInheritorProvider> directInheritorProviders = DirectInheritorProvider.EP_NAME.getExtensionList(myProject);
        Set<CompilerRef.CompilerClassHierarchyElementDef> result = new HashSet<>();
        Deque<CompilerRef.CompilerClassHierarchyElementDef> q = new ArrayDeque<>(10);
        q.addLast(hierarchyElement);
        while (!q.isEmpty()) {
          CompilerRef.CompilerClassHierarchyElementDef curClass = q.removeFirst();
          if (interruptNumber != -1 && result.size() > interruptNumber) {
            break;
          }
          if (result.add(curClass)) {
            if (result.size() % 100 == 0) {
              ProgressManager.checkCanceled();
            }

            if (!(curClass instanceof CompilerRef.CompilerAnonymousClassDef) && (checkBaseClassAmbiguity || curClass != hierarchyElement)) {
              if (hasMultipleDefinitions(curClass)) {
                return null;
              }
            }
            myIndex.get(JavaCompilerIndices.BACK_HIERARCHY).getData(curClass).forEach((id, children) -> {
              for (CompilerRef child : children) {
                if (child instanceof CompilerRef.CompilerClassHierarchyElementDef &&
                    (includeAnonymous || !(child instanceof CompilerRef.CompilerAnonymousClassDef))) {
                  q.addLast((CompilerRef.CompilerClassHierarchyElementDef)child);
                }
              }
              return true;
            });
            try {
              SearchId searchId = curClass instanceof SearchIdHolder
                                  ? ((SearchIdHolder)curClass).getSearchId()
                                  : CompilerHierarchySearchType.DIRECT_INHERITOR.convertToId(curClass, myIndex.getByteSeqEum());

              for (DirectInheritorProvider provider : directInheritorProviders) {
                q.addAll(provider.findDirectInheritors(searchId, myIndex.getByteSeqEum()));
              }
            }
            catch (IOException ignored) {
            }
          }
        }
        return result.toArray(CompilerRef.CompilerClassHierarchyElementDef.EMPTY_ARRAY);
      }
      catch (StorageException e) {
        throw new RuntimeException(e);
      }
    }
@Override
    public CompilerRef.CompilerClassHierarchyElementDef @Nullable("return null if the class hierarchy contains ambiguous qualified names") [] getHierarchy(CompilerRef.CompilerClassHierarchyElementDef hierarchyElement,
                                                                                                                                                           boolean checkBaseClassAmbiguity,
                                                                                                                                                           boolean includeAnonymous,
                                                                                                                                                           int interruptNumber)