boolean (final GlobalSearchScope scope, final TestClassFilter testClassFilter, @Nullable final Module module, final Set<? super PsiClass> found, final Set<? super PsiClass> processed, final String annotation, final Project project) { final Ref<Boolean> isJUnit4 = new Ref<>(Boolean.FALSE); // annotated with @Test final PsiClass testAnnotation = ReadAction.compute(() -> JavaPsiFacade.getInstance(project).findClass(annotation, GlobalSearchScope.allScope(project))); if (testAnnotation != null) { //allScope is used to find all abstract test cases which probably have inheritors in the current 'scope' GlobalSearchScope allScope = module == null ? GlobalSearchScope.allScope(project) : module.getModuleRuntimeScope(true); ClassesWithAnnotatedMembersSearch.search(testAnnotation, allScope).forEach(annotated -> { boolean success = ReadAction.compute(()-> { if (!processed.add(annotated)) { // don't process the same class twice regardless of it being in the scope return false; } final VirtualFile file = PsiUtilCore.getVirtualFile(annotated); if (file != null && scope.contains(file) && testClassFilter.isAccepted(annotated)) { if (!found.add(annotated)) { return false; } isJUnit4.set(Boolean.TRUE); } return true; }); if (!success) return true; ClassInheritorsSearch.search(annotated, scope, true, true, false).forEach(new ReadActionProcessor<>() { @Override public boolean processInReadAction(PsiClass aClass) { if (testClassFilter.isAccepted(aClass)) { found.add(aClass); processed.add(aClass); isJUnit4.set(Boolean.TRUE); } return true; } }); return true; }); } return isJUnit4.get().booleanValue(); }