private static void appendUsedRootDependencies(@NotNull Set<VirtualFile> usedRoots,
                                                 VirtualFile @NotNull [] givenRoots) {
    //classes per root
    Map<VirtualFile, Set<String>> fromClasses = new HashMap<>();
    //classes uses in root, ignoring self & jdk
    Map<VirtualFile, Set<String>> toClasses = new HashMap<>();
    collectClassesPerRoots(givenRoots, fromClasses, toClasses);

    Graph<VirtualFile> graph = GraphGenerator.generate(new InboundSemiGraph<>() {
      @NotNull
      @Override
      public Collection<VirtualFile> getNodes() {
        return Arrays.asList(givenRoots);
      }

      @NotNull
      @Override
      public Iterator<VirtualFile> getIn(VirtualFile n) {
        Set<String> classesInCurrentRoot = fromClasses.get(n);
        return toClasses.entrySet().stream()
          .filter(entry -> ContainerUtil.intersects(entry.getValue(), classesInCurrentRoot))
          .map(entry -> entry.getKey())
          .collect(Collectors.toSet()).iterator();
      }
    });

    GraphAlgorithms algorithms = GraphAlgorithms.getInstance();
    Set<VirtualFile> dependencies = new HashSet<>();
    for (VirtualFile root : usedRoots) {
      algorithms.collectOutsRecursively(graph, root, dependencies);
    }
    usedRoots.addAll(dependencies);
  }
private static void appendUsedRootDependencies(@NotNull Set<VirtualFile> usedRoots,
                                                 VirtualFile @NotNull [] givenRoots)