void (@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); }