private PackageDependenciesNode getModuleDirNode(VirtualFile virtualFile, Module module, DirectoryNode childNode) {
    if (virtualFile == null) {
      return getModuleNode(module);
    }

    PackageDependenciesNode directoryNode = myModuleDirNodes.get(virtualFile);
    if (directoryNode != null) {
      if (myCompactEmptyMiddlePackages) {
        final DirectoryNode nestedNode = ((DirectoryNode)directoryNode).getCompactedDirNode();
        if (nestedNode != null) { //decompact
          boolean expand = false;
          if (myTree != null){
            expand = !myTree.isCollapsed(new TreePath(directoryNode.getPath()));
          }
          DirectoryNode parentWrapper = nestedNode.getWrapper();
          while (parentWrapper.getWrapper() != null) {
            parentWrapper = parentWrapper.getWrapper();
          }
          for (int i = parentWrapper.getChildCount() - 1; i >= 0; i--) {
            nestedNode.add((MutableTreeNode)parentWrapper.getChildAt(i));
          }
          ((DirectoryNode)directoryNode).setCompactedDirNode(null);
          parentWrapper.add(nestedNode);
          nestedNode.removeUpReference();
          if (myTree != null && expand) {
            final Runnable expandRunnable = () -> myTree.expandPath(new TreePath(nestedNode.getPath()));
            SwingUtilities.invokeLater(expandRunnable);
          }
          return parentWrapper;
        }
        if (directoryNode.getParent() == null) {    //find first node in tree
          DirectoryNode parentWrapper = ((DirectoryNode)directoryNode).getWrapper();
          if (parentWrapper != null) {
            while (parentWrapper.getWrapper() != null) {
              parentWrapper = parentWrapper.getWrapper();
            }
            return parentWrapper;
          }
        }
      }
      return directoryNode;
    }

    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
    final VirtualFile sourceRoot = fileIndex.getSourceRootForFile(virtualFile);
    final VirtualFile contentRoot = fileIndex.getContentRootForFile(virtualFile);
    final VirtualFile classRoot = fileIndex.getClassRootForFile(virtualFile);

    directoryNode = new DirectoryNode(virtualFile, myProject, myCompactEmptyMiddlePackages, myFlattenPackages, myBaseDir,
                                      myContentRoots);
    myModuleDirNodes.put(virtualFile, (DirectoryNode)directoryNode);

    final VirtualFile directory = virtualFile.getParent();
    if (!myFlattenPackages && directory != null && !Comparing.equal(virtualFile, classRoot)) {
      if (myCompactEmptyMiddlePackages && !Comparing.equal(sourceRoot, virtualFile) && !Comparing.equal(contentRoot, virtualFile)) {//compact
        ((DirectoryNode)directoryNode).setCompactedDirNode(childNode);
      }
      if (fileIndex.getModuleForFile(directory) == module) {
        DirectoryNode parentDirectoryNode = myModuleDirNodes.get(directory);
        if (parentDirectoryNode != null
            || !myCompactEmptyMiddlePackages
            || (sourceRoot != null && VfsUtilCore.isAncestor(directory, sourceRoot, false) && fileIndex.getSourceRootForFile(directory) != null)
            || Comparing.equal(directory, contentRoot) 
            || Comparing.equal(directory, classRoot)) {
          getModuleDirNode(directory, module, (DirectoryNode)directoryNode).add(directoryNode);
        }
        else {
          directoryNode = getModuleDirNode(directory, module, (DirectoryNode)directoryNode);
        }
      }
      else {
        getModuleNode(module).add(directoryNode);
      }
    }
    else {
      if ((directory == null || Comparing.equal(virtualFile, classRoot)) && fileIndex.isInLibrary(virtualFile)) {
        List<OrderEntry> orderEntriesForFile = fileIndex.getOrderEntriesForFile(virtualFile);
        if (orderEntriesForFile.isEmpty()) {
          myRoot.add(directoryNode);
        }
        else {
          LibraryNode node = new LibraryNode(orderEntriesForFile.get(0), myProject);
          LibraryNode existingLibraryNode = getExistingLibraryNode(node);
          if (existingLibraryNode != null) {
            node = existingLibraryNode;
          }
          else {
            addExternalDepNode(node);
          }

          node.add(directoryNode);
        }
        return directoryNode;
      }

      if (Comparing.equal(contentRoot, virtualFile)) {
        getModuleNode(module).add(directoryNode);
      }
      else {
        final VirtualFile root;
        if (!Comparing.equal(sourceRoot, virtualFile) && sourceRoot != null) {
          root = sourceRoot;
        }
        else if (contentRoot != null) {
          root = contentRoot;
        }
        else {
          root = null;
        }
        if (root != null) {
          getModuleDirNode(root, module, null).add(directoryNode);
        } else {
          addExternalDepNode(directoryNode);
        }
      }
    }

    return directoryNode;
  }
private PackageDependenciesNode getModuleDirNode(VirtualFile virtualFile, Module module, DirectoryNode childNode)