private void processSearchRequests(@NotNull GlobalInspectionContext context) {
    RefManager refManager = context.getRefManager();
    AnalysisScope scope = refManager.getScope();

    SearchScope searchScope = new GlobalSearchScope(refManager.getProject()) {
      private final boolean processedReferences = Registry.is("batch.inspections.process.external.elements");

      @Override
      public boolean contains(@NotNull VirtualFile file) {
        if (scope != null && !scope.contains(file)) {
          return true;
        }
        //e.g. xml files were not included in the graph, so usages there should be processed as external
        boolean inGraph = processedReferences ? refManager.isInGraph(file) : FileTypeRegistry.getInstance().isFileOfType(file, JavaFileType.INSTANCE);
        return !inGraph;
      }

      @Override
      public boolean isSearchInModuleContent(@NotNull Module aModule) {
        return true;
      }

      @Override
      public boolean isSearchInLibraries() {
        return false;
      }
    };

    if (myDerivedClassesRequests != null) {
      List<SmartPsiElementPointer<?>> sortedIDs = getSortedIDs(myDerivedClassesRequests);
      for (SmartPsiElementPointer<?> sortedID : sortedIDs) {
        UClass uClass = ReadAction.compute(() -> UastContextKt.toUElement(dereferenceInReadAction(sortedID), UClass.class));
        if (uClass == null) continue;
        context.incrementJobDoneAmount(context.getStdJobDescriptors().FIND_EXTERNAL_USAGES, getClassPresentableName(uClass));

        List<DerivedClassesProcessor> processors = myDerivedClassesRequests.get(sortedID);
        LOG.assertTrue(processors != null, uClass.getClass().getName());
        Query<PsiClass> search = ClassInheritorsSearch.search(uClass.getJavaPsi(), searchScope, false);
        if (Registry.is("batch.inspections.process.external.usages.in.parallel")) search = search.allowParallelProcessing();
        search.forEach(createMembersProcessor(processors, scope));
      }

      myDerivedClassesRequests = null;
    }

    if (myDerivedMethodsRequests != null) {
      List<SmartPsiElementPointer<?>> sortedIDs = getSortedIDs(myDerivedMethodsRequests);
      for (SmartPsiElementPointer<?> sortedID : sortedIDs) {
        UMethod uMethod = ReadAction.compute(() -> UastContextKt.toUElement(dereferenceInReadAction(sortedID), UMethod.class));
        if (uMethod == null) continue;
        RefMethod refMethod = ReadAction.compute(() -> (RefMethod)refManager.getReference(uMethod.getSourcePsi()));

        context.incrementJobDoneAmount(context.getStdJobDescriptors().FIND_EXTERNAL_USAGES, refManager.getQualifiedName(refMethod));

        List<DerivedMethodsProcessor> processors = myDerivedMethodsRequests.get(sortedID);
        LOG.assertTrue(processors != null, uMethod.getClass().getName());
        Query<PsiMethod> search = OverridingMethodsSearch.search(uMethod.getJavaPsi(), searchScope, true);
        if (Registry.is("batch.inspections.process.external.usages.in.parallel")) search = search.allowParallelProcessing();
        search.forEach(createMembersProcessor(processors, scope));
      }

      myDerivedMethodsRequests = null;
    }

    if (myFieldUsagesRequests != null) {
      List<SmartPsiElementPointer<?>> sortedIDs = getSortedIDs(myFieldUsagesRequests);
      for (SmartPsiElementPointer<?> sortedID : sortedIDs) {
        PsiElement field = dereferenceInReadAction(sortedID);
        if (field == null) continue;
        List<UsagesProcessor> processors = myFieldUsagesRequests.get(sortedID);

        LOG.assertTrue(processors != null, field.getClass().getName());
        context.incrementJobDoneAmount(context.getStdJobDescriptors().FIND_EXTERNAL_USAGES, refManager.getQualifiedName(refManager.getReference(field)));

        Query<PsiReference> search = ReferencesSearch.search(field, searchScope, false);
        if (Registry.is("batch.inspections.process.external.usages.in.parallel")) search = search.allowParallelProcessing();
        search.forEach(new PsiReferenceProcessorAdapter(createReferenceProcessor(processors, context)));
      }

      myFieldUsagesRequests = null;
    }

    if (myClassUsagesRequests != null) {
      List<SmartPsiElementPointer<?>> sortedIDs = getSortedIDs(myClassUsagesRequests);
      for (SmartPsiElementPointer<?> sortedID : sortedIDs) {
        PsiElement classDeclaration = dereferenceInReadAction(sortedID);
        if (classDeclaration == null) continue;
        List<UsagesProcessor> processors = myClassUsagesRequests.get(sortedID);

        LOG.assertTrue(processors != null, classDeclaration.getClass().getName());
        UClass uClass = ReadAction.compute(() -> UastContextKt.toUElement(classDeclaration, UClass.class));
        String name = getClassPresentableName(uClass);
        context.incrementJobDoneAmount(context.getStdJobDescriptors().FIND_EXTERNAL_USAGES, name);

        Query<PsiReference> search = ReferencesSearch.search(classDeclaration, searchScope, false);
        if (Registry.is("batch.inspections.process.external.usages.in.parallel")) search = search.allowParallelProcessing();
        search.forEach(new PsiReferenceProcessorAdapter(createReferenceProcessor(processors, context)));
      }

      myClassUsagesRequests = null;
    }

    if (myMethodUsagesRequests != null) {
      List<SmartPsiElementPointer<?>> sortedIDs = getSortedIDs(myMethodUsagesRequests);
      for (SmartPsiElementPointer<?> sortedID : sortedIDs) {
        UMethod uMethod = ReadAction.compute(() -> UastContextKt.toUElement(dereferenceInReadAction(sortedID), UMethod.class));
        if (uMethod == null) continue;
        List<UsagesProcessor> processors = myMethodUsagesRequests.get(sortedID);

        LOG.assertTrue(processors != null, uMethod.getClass().getName());
        context.incrementJobDoneAmount(context.getStdJobDescriptors().FIND_EXTERNAL_USAGES, ReadAction.compute(() -> uMethod.getName()));

        PsiMethod javaMethod = ReadAction.compute(() -> uMethod.getJavaPsi());
        if (javaMethod != null) {
          Query<PsiReference> search = MethodReferencesSearch.search(javaMethod, searchScope, true);
          if (Registry.is("batch.inspections.process.external.usages.in.parallel")) search = search.allowParallelProcessing();
          search.forEach(new PsiReferenceProcessorAdapter(createReferenceProcessor(processors, context)));
        }
      }

      myMethodUsagesRequests = null;
    }

    if (myQNameUsagesRequests != null) {
      PsiSearchHelper helper = PsiSearchHelper.getInstance(refManager.getProject());
      RefJavaManager javaManager = refManager.getExtension(RefJavaManager.MANAGER);
      List<SmartPsiElementPointer<?>> sortedIDs = getSortedIDs(myQNameUsagesRequests);
      for (SmartPsiElementPointer<?> id : sortedIDs) {
        UClass uClass = ReadAction.compute(() -> UastContextKt.toUElement(dereferenceInReadAction(id), UClass.class));
        String qualifiedName = uClass != null ? ReadAction.compute(() -> uClass.getQualifiedName()) : null;
        if (qualifiedName != null) {
          List<Runnable> callbacks = myQNameUsagesRequests.get(id);
          GlobalSearchScope projectScope = GlobalSearchScope.projectScope(context.getProject());
          PsiNonJavaFileReferenceProcessor processor = (file, startOffset, endOffset) -> {
            for (Runnable callback : callbacks) {
              callback.run();
            }
            return false;
          };

          DelegatingGlobalSearchScope globalSearchScope = new DelegatingGlobalSearchScope(projectScope) {
            final Set<FileType> fileTypes = javaManager.getLanguages().stream().map(l -> l.getAssociatedFileType()).collect(Collectors.toSet());

            @Override
            public boolean contains(@NotNull VirtualFile file) {
              return !fileTypes.contains(file.getFileType()) && super.contains(file);
            }
          };

          helper.processUsagesInNonJavaFiles(qualifiedName, processor, globalSearchScope);
        }
      }


      myQNameUsagesRequests = null;
    }
  }
private void processSearchRequests(@NotNull GlobalInspectionContext context)