Couple<CheckedTreeNode> () { final Map<DataNode<?>, DataNodeCheckedTreeNode> treeNodeMap = new IdentityHashMap<>(); final Map<String, DataNode<?>> ideGroupingMap = new TreeMap<>(); // need order for assigning parents final DataNodeCheckedTreeNode[] preselectedNode = {null}; final DataNodeCheckedTreeNode[] rootModuleNode = {null}; final MultiMap<String, String> moduleDependenciesMap = MultiMap.create(); final Map<String, DataNode<Identifiable>> modulesNodeMap = new HashMap<>(); for (DataNode<ModuleDependencyData> moduleDependencyDataNode : ExternalSystemApiUtil.findAllRecursively( myProjectInfo.getExternalProjectStructure(), ProjectKeys.MODULE_DEPENDENCY)) { final ModuleDependencyData moduleDependencyData = moduleDependencyDataNode.getData(); moduleDependenciesMap.putValue( moduleDependencyData.getOwnerModule().getId(), moduleDependencyData.getTarget().getId()); } final int[] modulesCount = {0}; ExternalSystemApiUtil.visit(myProjectInfo.getExternalProjectStructure(), node -> { final Key key = node.getKey(); if (!myPublicKeys.contains(key)) return; DataNode modifiableDataNode = getModifiableDataNode(node); if (myDependencyAwareDataKeys.contains(key)) { modulesCount[0]++; } if (modifiableDataNode.isIgnored() && myShowSelectedRowsOnly) return; DataNodeCheckedTreeNode treeNode = treeNodeMap.get(node); if (treeNode == null) { treeNode = new DataNodeCheckedTreeNode(node); if (myDependencyAwareDataKeys.contains(key)) { final Identifiable moduleData = (Identifiable)node.getData(); //noinspection unchecked modulesNodeMap.put(moduleData.getId(), (DataNode<Identifiable>)node); } if (myPreselectedNodeObject != null && myPreselectedNodeObject.equals(node.getData())) { preselectedNode[0] = treeNode; } if (node.getData() instanceof ModuleData) { ModuleData moduleData = (ModuleData)node.getData(); if (key.equals(ProjectKeys.MODULE) && myProjectInfo.getExternalProjectPath().equals(moduleData.getLinkedExternalProjectPath())) { rootModuleNode[0] = treeNode; } String ideGrouping = moduleData.getIdeGrouping(); ideGroupingMap.put(ideGrouping, node); } else { // add elements under module node like web/enterprise artifacts DataNode<ModuleData> parentModule = node.getParent(ModuleData.class); if(parentModule != null) { DataNodeCheckedTreeNode moduleTreeNode = treeNodeMap.get(parentModule); if(moduleTreeNode != null) { moduleTreeNode.add(treeNode); treeNode.setParent(moduleTreeNode); } } } treeNode.setEnabled(myIgnorableKeys.contains(key)); treeNodeMap.put(node, treeNode); } }); for (Map.Entry<String, DataNode<?>> groupingEntry : ideGroupingMap.entrySet()) { DataNode node = groupingEntry.getValue(); if (!(node.getData() instanceof ModuleData moduleData)) continue; String ideParentGrouping = moduleData.getIdeParentGrouping(); DataNode structuralParent = ideParentGrouping != null ? ideGroupingMap.get(ideParentGrouping) : null; DataNodeCheckedTreeNode treeParentNode = structuralParent != null ? treeNodeMap.get(structuralParent) : null; DataNodeCheckedTreeNode treeNode = treeNodeMap.get(node); if (treeParentNode == null) { treeParentNode = treeNodeMap.get(node.getParent()); } if (treeNode == null || treeParentNode == null) continue; treeParentNode.add(treeNode); treeNode.setParent(treeParentNode); } myModulesCount = modulesCount[0]; dependentNodeMap.clear(); for (String moduleId : moduleDependenciesMap.keySet()) { final Collection<String> moduleDependencies = moduleDependenciesMap.get(moduleId); final DataNode<Identifiable> moduleNode = modulesNodeMap.get(moduleId); if (moduleNode != null) { dependentNodeMap.putValues(moduleNode, ContainerUtil.mapNotNull(moduleDependencies, modulesNodeMap::get)); } } final CheckedTreeNode root = new CheckedTreeNode(null); final DataNodeCheckedTreeNode projectNode = treeNodeMap.get(myProjectInfo.getExternalProjectStructure()); String rootModuleComment = ExternalSystemBundle.message("external.project.structure.project.root.module"); if (rootModuleNode[0] != null && projectNode != null) { rootModuleNode[0].comment = rootModuleComment; if (!projectNode.isNodeChild(rootModuleNode[0])) { projectNode.add(rootModuleNode[0]); } } List<TreeNode> nodes = projectNode != null ? TreeUtil.listChildren(projectNode) : ContainerUtil.emptyList(); nodes.sort((o1, o2) -> { if (o1 instanceof DataNodeCheckedTreeNode && o2 instanceof DataNodeCheckedTreeNode) { if (rootModuleComment.equals(((DataNodeCheckedTreeNode)o1).comment)) return -1; if (rootModuleComment.equals(((DataNodeCheckedTreeNode)o2).comment)) return 1; return StringUtil.naturalCompare(((DataNodeCheckedTreeNode)o1).text, ((DataNodeCheckedTreeNode)o2).text); } return 0; }); TreeUtil.addChildrenTo(root, nodes); return Couple.of(root, preselectedNode[0]); }