void (@NotNull final ArrayList<? super AbstractTreeNode<?>> children, @Nullable final Module module, @NotNull final TodoTreeBuilder builder) { Project project = getProject(); final PsiManager psiManager = PsiManager.getInstance(project); final List<VirtualFile> sourceRoots = new ArrayList<>(); if (module == null) { final ProjectRootManager projectRootManager = ProjectRootManager.getInstance(project); ContainerUtil.addAll(sourceRoots, projectRootManager.getContentSourceRoots()); } else { ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module); ContainerUtil.addAll(sourceRoots, moduleRootManager.getSourceRoots()); } final Set<PsiPackage> topLevelPackages = new HashSet<>(); for (final VirtualFile root : sourceRoots) { final PsiDirectory directory = psiManager.findDirectory(root); if (directory == null) { continue; } final PsiPackage directoryPackage = JavaDirectoryService.getInstance().getPackage(directory); if (directoryPackage == null || PackageUtil.isPackageDefault(directoryPackage)) { // add subpackages final PsiDirectory[] subdirectories = directory.getSubdirectories(); for (PsiDirectory subdirectory : subdirectories) { final PsiPackage aPackage = JavaDirectoryService.getInstance().getPackage(subdirectory); if (aPackage != null && !PackageUtil.isPackageDefault(aPackage)) { topLevelPackages.add(aPackage); } else { final Iterator<PsiFile> files = builder.getFiles(subdirectory); if (!files.hasNext()) continue; TodoDirNode dirNode = new TodoDirNode(project, subdirectory, builder); if (!children.contains(dirNode)){ children.add(dirNode); } } } // add non-dir items final Iterator<PsiFile> filesUnderDirectory = builder.getFilesUnderDirectory(directory); while (filesUnderDirectory.hasNext()) { final PsiFile file = filesUnderDirectory.next(); TodoFileNode todoFileNode = new TodoFileNode(project, file, builder, false); if (!children.contains(todoFileNode)){ children.add(todoFileNode); } } } else { // this is the case when a source root has pakage prefix assigned topLevelPackages.add(directoryPackage); } } GlobalSearchScope scope = module != null ? GlobalSearchScope.moduleScope(module) : GlobalSearchScope.projectScope(project); ArrayList<PsiPackage> packages = new ArrayList<>(); for (PsiPackage psiPackage : topLevelPackages) { final PsiPackage aPackage = findNonEmptyPackage(psiPackage, module, project, builder, scope); if (aPackage != null){ packages.add(aPackage); } } for (PsiPackage psiPackage : packages) { if (!builder.getTodoTreeStructure().getIsFlattenPackages()) { PackageElement element = new PackageElement(module, psiPackage, false); TodoPackageNode packageNode = new TodoPackageNode(project, element, builder, psiPackage.getQualifiedName()); if (!children.contains(packageNode)) { children.add(packageNode); } } else { Set<PsiPackage> allPackages = new HashSet<>(); traverseSubPackages(psiPackage, module, builder, project, allPackages); for (PsiPackage aPackage : allPackages) { TodoPackageNode packageNode = new TodoPackageNode(project, new PackageElement(module, aPackage, false), builder); if (!children.contains(packageNode)) { children.add(packageNode); } } } } final List<? extends VirtualFile> roots = collectContentRoots(module); roots.removeAll(sourceRoots); addDirsToChildren(roots, children, builder); }