private <T extends WordRequestInfo> int collectFiles(@NotNull Map<TextIndexQuery, Collection<T>> singles,
                                                       @NotNull Map<VirtualFile, Collection<T>> targetFiles,
                                                       @NotNull Map<VirtualFile, Collection<T>> nearDirectoryFiles,
                                                       @NotNull Map<VirtualFile, Collection<T>> containerNameFiles,
                                                       @NotNull Map<VirtualFile, Collection<T>> restFiles) {
    for (Map.Entry<TextIndexQuery, Collection<T>> entry : singles.entrySet()) {
      ProgressManager.checkCanceled();
      TextIndexQuery key = entry.getKey();
      if (key.isEmpty()) {
        continue;
      }
      Collection<T> processors = entry.getValue();
      GlobalSearchScope commonScope = uniteScopes(processors);
      // files which are target of the search
      Set<VirtualFile> thisTargetFiles = ReadAction.compute(() -> processors.stream().flatMap(p -> p.getSearchSession().getTargetVirtualFiles().stream()).filter(commonScope::contains).collect(Collectors.toSet()));
      // directories in which target files are contained
      Set<VirtualFile> thisTargetDirectories = ContainerUtil.map2SetNotNull(thisTargetFiles, f -> f.getParent());
      Set<VirtualFile> intersectionWithContainerNameFiles = intersectionWithContainerNameFiles(commonScope, processors, key);
      List<VirtualFile> allFilesForKeys = new ArrayList<>();
      processFilesContainingAllKeys(myManager.getProject(), commonScope, Processors.cancelableCollectProcessor(allFilesForKeys), key);
      Object2IntMap<VirtualFile> file2Mask=new Object2IntOpenHashMap<>();
      file2Mask.defaultReturnValue(-1);
      IntRef maskRef = new IntRef();
      for (VirtualFile file : allFilesForKeys) {
        ProgressManager.checkCanceled();
        for (IdIndexEntry indexEntry : key.myIdIndexEntries) {
          ProgressManager.checkCanceled();
          maskRef.set(0);
          myDumbService.runReadActionInSmartMode(
            () -> FileBasedIndex.getInstance().processValues(IdIndex.NAME, indexEntry, file, (__, value) -> {
              maskRef.set(value);
              return true;
            }, commonScope));
          int oldMask = file2Mask.getOrDefault(file, UsageSearchContext.ANY);
          file2Mask.put(file, oldMask & maskRef.get());
        }
      }

      for (Object2IntMap.Entry<VirtualFile> fileEntry : file2Mask.object2IntEntrySet()) {
        VirtualFile file = fileEntry.getKey();
        int mask = fileEntry.getIntValue();
        myDumbService.runReadActionInSmartMode(() -> {
          Map<VirtualFile, Collection<T>> result =
            thisTargetFiles.contains(file)
            ? targetFiles
            : thisTargetDirectories.contains(file.getParent())
              ? nearDirectoryFiles
              : intersectionWithContainerNameFiles != null && intersectionWithContainerNameFiles.contains(file)
                ? containerNameFiles
                : restFiles;
          for (T single : processors) {
            ProgressManager.checkCanceled();
            if ((mask & single.getSearchContext()) != 0 && single.getSearchScope().contains(file)) {
              result.computeIfAbsent(file, ___ -> new SmartList<>()).add(single);
            }
          }
        });
      }
    }
    return targetFiles.size() + nearDirectoryFiles.size() + containerNameFiles.size() + restFiles.size();
  }
private <T extends WordRequestInfo> int collectFiles(@NotNull Map<TextIndexQuery, Collection<T>> singles,
                                                       @NotNull Map<VirtualFile, Collection<T>> targetFiles,
                                                       @NotNull Map<VirtualFile, Collection<T>> nearDirectoryFiles,
                                                       @NotNull Map<VirtualFile, Collection<T>> containerNameFiles,
                                                       @NotNull Map<VirtualFile, Collection<T>> restFiles)