void (PsiClass containingClass, List<? super PsiClass> classes, HashSet<? super PsiClass> visited) { if (!visited.add(containingClass)) return; Set<PsiClass> containers = new HashSet<>(); final boolean isJUnit5 = ReadAction.compute(() -> JUnitUtil.isJUnit5(containingClass)); ClassInheritorsSearch.search(containingClass).forEach(aClass -> { PsiClass container = aClass.getContainingClass(); if (container != null && container.hasModifierProperty(PsiModifier.ABSTRACT)) { containers.add(container); } if (isJUnit5 && JUnitUtil.isJUnit5TestClass(aClass, true) || PsiClassUtil.isRunnableClass(aClass, true, true)) { classes.add(aClass); } return true; }); for (PsiClass container : containers) { collectClasses(container, classes, visited); } }