private void createNodesGroupedByDirectory(
      CheckedTreeNode root, final List<? extends DetectedFrameworkDescription> frameworks) {
    Map<VirtualFile, FrameworkDirectoryNode> nodes = new HashMap<>();
    List<DetectedFrameworkNode> externalNodes = new ArrayList<>();
    for (DetectedFrameworkDescription framework : frameworks) {
      VirtualFile parent = VfsUtil.getCommonAncestor(framework.getRelatedFiles());
      if (parent != null && !parent.isDirectory()) {
        parent = parent.getParent();
      }

      final DetectedFrameworkNode frameworkNode = new DetectedFrameworkNode(framework, myContext);
      if (parent != null) {
        createDirectoryNodes(parent, nodes).add(frameworkNode);
      } else {
        externalNodes.add(frameworkNode);
      }
    }
    List<FrameworkDirectoryNode> rootDirs = new ArrayList<>();
    for (FrameworkDirectoryNode directoryNode : nodes.values()) {
      if (directoryNode.getParent() == null) {
        rootDirs.add(directoryNode);
      }
    }
    for (FrameworkDirectoryNode dir : rootDirs) {
      root.add(collapseDirectoryNode(dir));
    }
    for (DetectedFrameworkNode node : externalNodes) {
      root.add(node);
    }
  }
 private static FrameworkDirectoryNode collapseDirectoryNode(FrameworkDirectoryNode node) {
   if (node.getChildCount() == 1) {
     final TreeNode child = node.getChildAt(0);
     if (child instanceof FrameworkDirectoryNode) {
       return collapseDirectoryNode((FrameworkDirectoryNode) child);
     }
   }
   for (int i = 0; i < node.getChildCount(); i++) {
     TreeNode child = node.getChildAt(i);
     if (child instanceof FrameworkDirectoryNode) {
       final FrameworkDirectoryNode collapsed =
           collapseDirectoryNode((FrameworkDirectoryNode) child);
       if (collapsed != child) {
         node.remove(i);
         node.insert(collapsed, i);
       }
     }
   }
   return node;
 }