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 VirtualFile[] getFilesToCheckReadonlyStatus(
     GeneratingCompiler.GenerationItem[] items) {
   List<VirtualFile> filesToCheck = new ArrayList<VirtualFile>();
   for (GeneratingCompiler.GenerationItem item : items) {
     if (item instanceof AndroidAptCompiler.AptGenerationItem) {
       final Set<File> generatedFiles =
           ((AndroidAptCompiler.AptGenerationItem) item).getGeneratedFiles().keySet();
       for (File generatedFile : generatedFiles) {
         if (generatedFile.exists()) {
           VirtualFile generatedVFile =
               LocalFileSystem.getInstance().findFileByIoFile(generatedFile);
           if (generatedVFile != null) {
             filesToCheck.add(generatedVFile);
           }
         }
       }
     }
   }
   return VfsUtil.toVirtualFileArray(filesToCheck);
 }
  private static void addFileToJar(
      @NotNull JarOutputStream jar,
      @NotNull File file,
      @NotNull File rootDirectory,
      boolean packRClasses)
      throws IOException {

    if (file.isDirectory()) {
      for (File child : file.listFiles()) {
        addFileToJar(jar, child, rootDirectory, packRClasses);
      }
    } else if (file.isFile()) {
      if (!FileUtil.getExtension(file.getName()).equals("class")) {
        return;
      }

      if (!packRClasses && R_PATTERN.matcher(file.getName()).matches()) {
        return;
      }

      final String rootPath = rootDirectory.getAbsolutePath();

      String path = file.getAbsolutePath();
      path = FileUtil.toSystemIndependentName(path.substring(rootPath.length()));
      if (path.charAt(0) == '/') {
        path = path.substring(1);
      }

      final JarEntry entry = new JarEntry(path);
      entry.setTime(file.lastModified());
      jar.putNextEntry(entry);

      BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
      try {
        final byte[] buffer = new byte[1024];
        int count;
        while ((count = bis.read(buffer)) != -1) {
          jar.write(buffer, 0, count);
        }
        jar.closeEntry();
      } finally {
        bis.close();
      }
    }
  }
  public static void removeDuplicatingClasses(
      final Module module,
      @NotNull final String packageName,
      @NotNull String className,
      @Nullable File classFile,
      String sourceRootPath) {
    if (sourceRootPath == null) {
      return;
    }
    VirtualFile sourceRoot = LocalFileSystem.getInstance().findFileByPath(sourceRootPath);
    if (sourceRoot == null) {
      return;
    }
    final Project project = module.getProject();
    final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
    final String interfaceQualifiedName = packageName + '.' + className;
    PsiClass[] classes =
        facade.findClasses(interfaceQualifiedName, GlobalSearchScope.moduleScope(module));
    final ProjectFileIndex projectFileIndex =
        ProjectRootManager.getInstance(project).getFileIndex();
    for (PsiClass c : classes) {
      PsiFile psiFile = c.getContainingFile();
      if (className.equals(FileUtil.getNameWithoutExtension(psiFile.getName()))) {
        VirtualFile virtualFile = psiFile.getVirtualFile();
        if (virtualFile != null
            && projectFileIndex.getSourceRootForFile(virtualFile) == sourceRoot) {
          final String path = virtualFile.getPath();
          File f = new File(path);

          try {
            f = f.getCanonicalFile();
            classFile = classFile != null ? classFile.getCanonicalFile() : null;
            if (f != null && !f.equals(classFile) && f.exists()) {
              if (f.delete()) {
                virtualFile.refresh(true, false);
              } else {
                ApplicationManager.getApplication()
                    .invokeLater(
                        new Runnable() {
                          public void run() {
                            Messages.showErrorDialog(
                                project, "Can't delete file " + path, CommonBundle.getErrorTitle());
                          }
                        },
                        project.getDisposed());
              }
            }
          } catch (IOException e) {
            LOG.info(e);
          }
        }
      }
    }
  }
  public static void packClassFilesIntoJar(
      @NotNull String[] firstPackageDirPaths,
      @NotNull String[] libFirstPackageDirPaths,
      @NotNull File jarFile)
      throws IOException {
    final JarOutputStream jos = new JarOutputStream(new FileOutputStream(jarFile));
    try {
      for (String path : firstPackageDirPaths) {
        final File firstPackageDir = new File(path);
        if (firstPackageDir.exists()) {
          addFileToJar(jos, firstPackageDir, firstPackageDir.getParentFile(), true);
        }
      }

      for (String path : libFirstPackageDirPaths) {
        final File firstPackageDir = new File(path);
        if (firstPackageDir.exists()) {
          addFileToJar(jos, firstPackageDir, firstPackageDir.getParentFile(), false);
        }
      }
    } finally {
      jos.close();
    }
  }
  @Nullable
  public static String findResourcesCacheDirectory(
      @NotNull Module module, boolean createIfNotFound, @Nullable CompileContext context) {
    final Project project = module.getProject();

    final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(project);
    if (extension == null) {
      if (context != null) {
        context.addMessage(
            CompilerMessageCategory.ERROR,
            "Cannot get compiler settings for project " + project.getName(),
            null,
            -1,
            -1);
      }
      return null;
    }

    final String projectOutputDirUrl = extension.getCompilerOutputUrl();
    if (projectOutputDirUrl == null) {
      if (context != null) {
        context.addMessage(
            CompilerMessageCategory.ERROR,
            "Cannot find output directory for project " + project.getName(),
            null,
            -1,
            -1);
      }
      return null;
    }

    final String pngCacheDirPath =
        VfsUtil.urlToPath(projectOutputDirUrl)
            + '/'
            + RESOURCES_CACHE_DIR_NAME
            + '/'
            + module.getName();
    final String pngCacheDirOsPath = FileUtil.toSystemDependentName(pngCacheDirPath);

    final File pngCacheDir = new File(pngCacheDirOsPath);
    if (pngCacheDir.exists()) {
      if (pngCacheDir.isDirectory()) {
        return pngCacheDirOsPath;
      } else {
        if (context != null) {
          context.addMessage(
              CompilerMessageCategory.ERROR,
              "Cannot create directory " + pngCacheDirOsPath + " because file already exists",
              null,
              -1,
              -1);
        }
        return null;
      }
    }

    if (!createIfNotFound) {
      return null;
    }

    if (!pngCacheDir.mkdirs()) {
      if (context != null) {
        context.addMessage(
            CompilerMessageCategory.ERROR,
            "Cannot create directory " + pngCacheDirOsPath,
            null,
            -1,
            -1);
      }
      return null;
    }

    return pngCacheDirOsPath;
  }