@Override
  public boolean queryExternalUsagesRequests(@NotNull InspectionManager manager,
                                             @NotNull GlobalInspectionContext globalContext,
                                             @NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor) {
    checkForReachableRefs(globalContext);
    int phase = Objects.requireNonNull(globalContext.getUserData(PHASE_KEY));
    if (phase == 2) {
      globalContext.putUserData(PROCESSED_SUSPICIOUS_ELEMENTS_KEY, null);
      return false;
    }
    Set<RefElement> processedSuspicious = globalContext.getUserData(PROCESSED_SUSPICIOUS_ELEMENTS_KEY);

    boolean firstPhase = phase == 1;
    RefFilter filter = firstPhase ? new StrictUnreferencedFilter(this, globalContext) : new RefUnreachableFilter(this, globalContext);
    LOG.assertTrue(processedSuspicious != null, "phase: " + phase);

    Collection<Language> uastLanguages = Language.findInstance(UastMetaLanguage.class).getMatchingLanguages();
    globalContext.getRefManager().iterate(new RefJavaVisitor() {
      @Override
      public void visitField(@NotNull RefField refField) {
        if (!filter.accepts(refField) || processedSuspicious.contains(refField)) {
          return;
        }
        processedSuspicious.add(refField);
        UField uField = refField.getUastElement();
        if (uField != null && RefSerializationUtil.isSerializationImplicitlyUsedField(uField)) {
          getEntryPointsManager(globalContext).addEntryPoint(refField, false);
        }
        else {
          globalContext.getExtension(GlobalJavaInspectionContext.CONTEXT).enqueueFieldUsagesProcessor(refField, psiReference -> {
            getEntryPointsManager(globalContext).addEntryPoint(refField, false);
            return false;
          });
        }
      }

      @Override
      public void visitMethod(@NotNull RefMethod refMethod) {
        if (!filter.accepts(refMethod) || processedSuspicious.contains(refMethod)) {
          return;
        }
        processedSuspicious.add(refMethod);
        if (refMethod instanceof RefImplicitConstructor ctor) {
          RefClass ownerClass = ctor.getOwnerClass();
          doVisitClass(ownerClass);
          return;
        }
        if (refMethod.isConstructor()) {
          RefClass ownerClass = refMethod.getOwnerClass();
          if (ownerClass != null) {
            queryQualifiedNameUsages(ownerClass);
          }
        }
        UMethod uMethod = refMethod.getUastElement();
        if (uMethod != null && (RefSerializationUtil.isSerializationMethod(uMethod, refMethod.getOwnerClass()))) {
          getEntryPointsManager(globalContext).addEntryPoint(refMethod, false);
        }
        else if (!refMethod.isExternalOverride() && !PsiModifier.PRIVATE.equals(refMethod.getAccessModifier())) {
          processedSuspicious.addAll(refMethod.getDerivedMethods());
          enqueueMethodUsages(globalContext, refMethod);
        }
      }

      @Override
      public void visitClass(@NotNull RefClass refClass) {
        if (!filter.accepts(refClass) || processedSuspicious.contains(refClass)) {
          return;
        }
        doVisitClass(refClass);
      }

      private void doVisitClass(@NotNull RefClass refClass) {
        if (!refClass.isAnonymous()) {
          processedSuspicious.add(refClass);
          globalContext.getExtension(GlobalJavaInspectionContext.CONTEXT).enqueueDerivedClassesProcessor(refClass, inheritor -> {
            getEntryPointsManager(globalContext).addEntryPoint(refClass, false);
            return false;
          });

          globalContext.getExtension(GlobalJavaInspectionContext.CONTEXT).enqueueClassUsagesProcessor(refClass, reference -> {
            if (!isAddNonJavaUsedEnabled() && !uastLanguages.contains(reference.getElement().getLanguage())) return true;
            getEntryPointsManager(globalContext).addEntryPoint(refClass, false);
            return false;
          });

          queryQualifiedNameUsages(refClass);
        }
      }

      void queryQualifiedNameUsages(@NotNull RefClass refClass) {
        if (firstPhase && isAddNonJavaUsedEnabled()) {
          globalContext.getExtension(GlobalJavaInspectionContext.CONTEXT).enqueueQualifiedNameOccurrencesProcessor(refClass, () -> {
            EntryPointsManager entryPointsManager = getEntryPointsManager(globalContext);
            entryPointsManager.addEntryPoint(refClass, false);
            for (RefMethod constructor : refClass.getConstructors()) {
              entryPointsManager.addEntryPoint(constructor, false);
            }
          });

          //references from java-like are already in graph, or
          //they would be checked during GlobalJavaInspectionContextImpl.performPostRunActivities
          for (RefElement element : refClass.getInReferences()) {
            if (!(element instanceof RefJavaElement)) {
              getEntryPointsManager(globalContext).addEntryPoint(refClass, false);
            }
          }
        }
      }
    });
    globalContext.putUserData(PHASE_KEY, 2);

    return true;
  }
@Override
  public boolean queryExternalUsagesRequests(@NotNull InspectionManager manager,
                                             @NotNull GlobalInspectionContext globalContext,
                                             @NotNull ProblemDescriptionsProcessor problemDescriptionsProcessor)