List<Set<PsiJavaModule>> (Project project) { Set<PsiJavaModule> projectModules = new HashSet<>(); for (Module module : ModuleManager.getInstance(project).getModules()) { ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); List<PsiJavaModule> descriptors = ContainerUtil.mapNotNull(moduleRootManager.getSourceRoots(true), root -> findDescriptorByFile(root, project)); if (descriptors.size() > 2) return Collections.emptyList(); // aborts the process when there are incorrect modules in the project if (descriptors.size() == 2) { if (descriptors.stream() .map(d -> PsiUtilCore.getVirtualFile(d)) .filter(Objects::nonNull) .map(moduleRootManager.getFileIndex()::isInTestSourceContent).count() < 2) { return Collections.emptyList(); } projectModules.addAll(descriptors); } if (descriptors.size() == 1) projectModules.add(descriptors.get(0)); } if (!projectModules.isEmpty()) { MultiMap<PsiJavaModule, PsiJavaModule> relations = MultiMap.create(); for (PsiJavaModule module : projectModules) { for (PsiRequiresStatement statement : module.getRequires()) { PsiJavaModuleReference ref = statement.getModuleReference(); if (ref != null) { ResolveResult[] results = ref.multiResolve(true); if (results.length == 1) { PsiJavaModule dependency = (PsiJavaModule)results[0].getElement(); if (dependency != null && projectModules.contains(dependency)) { relations.putValue(module, dependency); } } } } } if (!relations.isEmpty()) { Graph<PsiJavaModule> graph = new ChameleonGraph<>(relations, false); DFSTBuilder<PsiJavaModule> builder = new DFSTBuilder<>(graph); Collection<Collection<PsiJavaModule>> components = builder.getComponents(); if (!components.isEmpty()) { return ContainerUtil.map(components, elements -> new LinkedHashSet<>(elements)); } } } return Collections.emptyList(); }