public ContentRoot getContentRoot(IjModule module) throws IOException {
   Path moduleBasePath = module.getModuleBasePath();
   Path moduleLocation = module.getModuleImlFilePath();
   final Path moduleLocationBasePath =
       (moduleLocation.getParent() == null) ? Paths.get("") : moduleLocation.getParent();
   ImmutableSet<IjFolder> sourcesAndExcludes =
       FluentIterable.from(module.getFolders()).append(createExcludes(module)).toSet();
   return createContentRoot(moduleBasePath, sourcesAndExcludes, moduleLocationBasePath);
 }
 public static ImmutableSet<Path> createReferencedFolderPathsSet(ImmutableSet<IjModule> modules) {
   Set<Path> pathSet = new HashSet<>();
   for (IjModule module : modules) {
     addPathAndParents(pathSet, module.getModuleBasePath());
     for (IjFolder folder : module.getFolders()) {
       addPathAndParents(pathSet, folder.getPath());
     }
   }
   return ImmutableSet.copyOf(pathSet);
 }
  public ImmutableSet<IjFolder> createExcludes(IjModule module) throws IOException {
    final ImmutableSet.Builder<IjFolder> excludesBuilder = ImmutableSet.builder();
    final Path moduleBasePath = module.getModuleBasePath();
    projectFilesystem.walkRelativeFileTree(
        moduleBasePath,
        new FileVisitor<Path>() {
          @Override
          public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
              throws IOException {
            // This is another module that's nested in this one. The entire subtree will be handled
            // When we create excludes for that module.
            if (filesystemTraversalBoundaryPaths.contains(dir) && !moduleBasePath.equals(dir)) {
              return FileVisitResult.SKIP_SUBTREE;
            }
            if (!referencedFolderPaths.contains(dir)) {
              excludesBuilder.add(new ExcludeFolder(dir));
              return FileVisitResult.SKIP_SUBTREE;
            }

            return FileVisitResult.CONTINUE;
          }

          @Override
          public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
              throws IOException {
            return FileVisitResult.CONTINUE;
          }

          @Override
          public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
            return FileVisitResult.CONTINUE;
          }

          @Override
          public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
            return FileVisitResult.CONTINUE;
          }
        });
    return excludesBuilder.build();
  }