void (@NotNull List<? extends PsiElement> elements, @NotNull Collection<? super LineMarkerInfo<?>> result) { ApplicationManager.getApplication().assertReadAccessAllowed(); List<Computable<List<LineMarkerInfo<PsiElement>>>> tasks = new ArrayList<>(); MultiMap<PsiClass, PsiMethod> canBeOverridden = MultiMap.createSet(); MultiMap<PsiClass, PsiMethod> canHaveSiblings = MultiMap.create(); //noinspection ForLoopReplaceableByForEach for (int i = 0; i < elements.size(); i++) { PsiElement element = elements.get(i); ProgressManager.checkCanceled(); if (!(element instanceof PsiIdentifier)) continue; PsiElement parent = element.getParent(); if (parent instanceof PsiMethod method) { PsiClass containingClass = method.getContainingClass(); if (containingClass != null && PsiUtil.canBeOverridden(method)) { canBeOverridden.putValue(containingClass, method); } if (mySiblingsOption.isEnabled() && FindSuperElementsHelper.canHaveSiblingSuper(method, containingClass)) { canHaveSiblings.putValue(containingClass, method); } if (JavaServiceUtil.isServiceProviderMethod(method)) { tasks.add(() -> JavaServiceUtil.collectServiceProviderMethod(method)); } } else if (parent instanceof PsiClass && !(parent instanceof PsiTypeParameter)) { tasks.add(() -> collectInheritingClasses((PsiClass)parent)); tasks.add(() -> JavaServiceUtil.collectServiceImplementationClass((PsiClass)parent)); } else if (parent instanceof PsiReferenceExpression && parent.getParent() instanceof PsiMethodCallExpression parentCall && JavaServiceUtil.SERVICE_LOADER_LOAD.test(parentCall)) { tasks.add(() -> JavaServiceUtil.collectServiceLoaderLoadCall((PsiIdentifier)element, parentCall)); } } for (Map.Entry<PsiClass, Collection<PsiMethod>> entry : canBeOverridden.entrySet()) { PsiClass psiClass = entry.getKey(); Set<PsiMethod> methods = (Set<PsiMethod>)entry.getValue(); tasks.add(() -> collectOverridingMethods(methods, psiClass)); } for (PsiClass psiClass : canHaveSiblings.keySet()) { Collection<PsiMethod> methods = canHaveSiblings.get(psiClass); tasks.add(() -> collectSiblingInheritedMethods(methods)); } Object lock = new Object(); ProgressIndicator indicator = ProgressIndicatorProvider.getGlobalProgressIndicator(); List<LineMarkerInfo<PsiElement>> found = new ArrayList<>(); JobLauncher.getInstance().invokeConcurrentlyUnderProgress(tasks, indicator, computable -> { List<LineMarkerInfo<PsiElement>> infos = computable.compute(); synchronized (lock) { found.addAll(infos); } return true; }); synchronized (lock) { result.addAll(found); } }