public static void createSourceRootIfNotExist(
      @NotNull final String path, @NotNull final Module module) {
    ApplicationManager.getApplication().assertIsDispatchThread();

    final File rootFile = new File(path);
    final boolean created;
    if (!rootFile.exists()) {
      if (!rootFile.mkdirs()) return;
      created = true;
    } else {
      created = false;
    }

    final Project project = module.getProject();
    Module genModule = module;

    final AndroidFacet facet = AndroidFacet.getInstance(genModule);

    if (facet != null && facet.getConfiguration().LIBRARY_PROJECT) {
      removeGenModule(module);
    }

    if (project.isDisposed() || genModule.isDisposed()) {
      return;
    }

    final VirtualFile root;
    if (created) {
      root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(rootFile);
    } else {
      root = LocalFileSystem.getInstance().findFileByIoFile(rootFile);
    }
    if (root != null) {
      final ModuleRootManager manager = ModuleRootManager.getInstance(genModule);
      unexcludeRootIfNeccessary(root, manager);
      for (VirtualFile existingRoot : manager.getSourceRoots()) {
        if (existingRoot == root) return;
      }
      ApplicationManager.getApplication()
          .runWriteAction(
              new Runnable() {
                public void run() {
                  addSourceRoot(manager, root);
                }
              });
    }
  }
 private static void collectModules(Module module, Set<Module> result, Module[] allModules) {
   if (!result.add(module)) {
     return;
   }
   for (Module otherModule : allModules) {
     if (ModuleRootManager.getInstance(otherModule).isDependsOn(module)) {
       collectModules(otherModule, result, allModules);
     }
   }
 }
 public static void addSourceRoot(
     final ModuleRootManager manager, @NotNull final VirtualFile root) {
   final ModifiableRootModel model = manager.getModifiableModel();
   ContentEntry contentEntry = findContentEntryForRoot(model, root);
   if (contentEntry == null) {
     contentEntry = model.addContentEntry(root);
   }
   contentEntry.addSourceFolder(root, false);
   model.commit();
 }
 private static void unexcludeRootIfNeccessary(
     @NotNull VirtualFile root, @NotNull ModuleRootManager manager) {
   Set<VirtualFile> excludedRoots =
       new HashSet<VirtualFile>(Arrays.asList(manager.getExcludeRoots()));
   VirtualFile excludedRoot = root;
   while (excludedRoot != null && !excludedRoots.contains(excludedRoot)) {
     excludedRoot = excludedRoot.getParent();
   }
   if (excludedRoot == null) {
     return;
   }
   Set<VirtualFile> rootsToExclude = new HashSet<VirtualFile>();
   collectChildrenRecursively(excludedRoot, root, rootsToExclude);
   final ModifiableRootModel model = manager.getModifiableModel();
   ContentEntry contentEntry = findContentEntryForRoot(model, excludedRoot);
   if (contentEntry != null) {
     ExcludeFolder excludedFolder = null;
     for (ExcludeFolder folder : contentEntry.getExcludeFolders()) {
       if (folder.getFile() == excludedRoot) {
         excludedFolder = folder;
         break;
       }
     }
     if (excludedFolder != null) {
       contentEntry.removeExcludeFolder(excludedFolder);
     }
     for (VirtualFile rootToExclude : rootsToExclude) {
       if (!excludedRoots.contains(rootToExclude)) {
         contentEntry.addExcludeFolder(rootToExclude);
       }
     }
   }
   ApplicationManager.getApplication()
       .runWriteAction(
           new Runnable() {
             @Override
             public void run() {
               model.commit();
             }
           });
 }
  private static void removeGenModule(@NotNull final Module libModule) {
    final String genModuleName = getGenModuleName(libModule);
    final ModuleManager moduleManager = ModuleManager.getInstance(libModule.getProject());
    final ModifiableRootModel model = ModuleRootManager.getInstance(libModule).getModifiableModel();

    for (OrderEntry entry : model.getOrderEntries()) {
      if (entry instanceof ModuleOrderEntry
          && genModuleName.equals(((ModuleOrderEntry) entry).getModuleName())) {
        model.removeOrderEntry(entry);
      }
    }

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                model.commit();
              }
            });

    final Module genModule = moduleManager.findModuleByName(genModuleName);
    if (genModule == null) {
      return;
    }
    moduleManager.disposeModule(genModule);

    final VirtualFile moduleFile = genModule.getModuleFile();

    if (moduleFile != null) {
      ApplicationManager.getApplication()
          .invokeLater(
              new Runnable() {
                @Override
                public void run() {
                  ApplicationManager.getApplication()
                      .runWriteAction(
                          new Runnable() {
                            @Override
                            public void run() {
                              try {
                                moduleFile.delete(libModule.getProject());
                              } catch (IOException e) {
                                LOG.error(e);
                              }
                            }
                          });
                }
              });
    }
  }
  private static void removeSourceRoot(@NotNull Module module, @NotNull final VirtualFile root) {
    final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
    final ContentEntry contentEntry = findContentEntryForRoot(model, root);

    if (contentEntry != null) {
      for (SourceFolder sourceFolder : contentEntry.getSourceFolders()) {
        if (sourceFolder.getFile() == root) {
          contentEntry.removeSourceFolder(sourceFolder);
        }
      }
    }

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                model.commit();
              }
            });
  }