private void compileFinished(int exitValue, final ModuleChunk chunk, final String outputDir) {
    if (exitValue != 0
        && !myCompileContext.getProgressIndicator().isCanceled()
        && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
      myCompileContext.addMessage(
          CompilerMessageCategory.ERROR,
          CompilerBundle.message("error.compiler.internal.error", exitValue),
          null,
          -1,
          -1);
    }

    myCompiler.compileFinished();
    final List<File> toRefresh = new ArrayList<File>();
    final Map<String, Collection<TranslatingCompiler.OutputItem>> results =
        new HashMap<String, Collection<TranslatingCompiler.OutputItem>>();
    try {
      final FileTypeManager typeManager = FileTypeManager.getInstance();
      final String outputDirPath = outputDir.replace(File.separatorChar, '/');
      try {
        for (final Module module : chunk.getModules()) {
          for (final VirtualFile root : chunk.getSourceRoots(module)) {
            final String packagePrefix = myProjectFileIndex.getPackageNameByDirectory(root);
            if (LOG.isDebugEnabled()) {
              LOG.debug(
                  "Building output items for "
                      + root.getPresentableUrl()
                      + "; output dir = "
                      + outputDirPath
                      + "; packagePrefix = \""
                      + packagePrefix
                      + "\"");
            }
            buildOutputItemsList(
                outputDirPath, module, root, typeManager, root, packagePrefix, toRefresh, results);
          }
        }
      } catch (CacheCorruptedException e) {
        myCompileContext.requestRebuildNextTime(
            CompilerBundle.message("error.compiler.caches.corrupted"));
        if (LOG.isDebugEnabled()) {
          LOG.debug(e);
        }
      }
    } finally {
      CompilerUtil.refreshIOFiles(toRefresh);
      for (Iterator<Map.Entry<String, Collection<TranslatingCompiler.OutputItem>>> it =
              results.entrySet().iterator();
          it.hasNext(); ) {
        Map.Entry<String, Collection<TranslatingCompiler.OutputItem>> entry = it.next();
        mySink.add(entry.getKey(), entry.getValue(), VirtualFile.EMPTY_ARRAY);
        it.remove(); // to free memory
      }
    }
    myFileNameToSourceMap.clear(); // clear the map before the next use
  }
 private void updateStatistics() {
   final String msg;
   String moduleName = myModuleName;
   if (moduleName != null) {
     msg =
         CompilerBundle.message(
             "statistics.files.classes.module",
             myStatistics.getFilesCount(),
             myStatistics.getClassesCount(),
             moduleName);
   } else {
     msg =
         CompilerBundle.message(
             "statistics.files.classes",
             myStatistics.getFilesCount(),
             myStatistics.getClassesCount());
   }
   myCompileContext.getProgressIndicator().setText2(msg);
   // myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount
   // /myTotalFilesToCompile);
 }
  public void compile() throws CompilerException, CacheCorruptedException {
    Application application = ApplicationManager.getApplication();
    try {
      if (!myFilesToCompile.isEmpty()) {
        if (application.isUnitTestMode()) {
          saveTestData();
        }
        compileModules(buildModuleToFilesMap(myFilesToCompile));
      }
    } catch (SecurityException e) {
      throw new CompilerException(
          CompilerBundle.message("error.compiler.process.not.started", e.getMessage()), e);
    } catch (IllegalArgumentException e) {
      throw new CompilerException(e.getMessage(), e);
    } finally {
      for (final VirtualFile file : myModuleToTempDirMap.values()) {
        if (file != null) {
          final File ioFile = new File(file.getPath());
          FileUtil.asyncDelete(ioFile);
        }
      }
      myModuleToTempDirMap.clear();
    }

    if (!myFilesToCompile.isEmpty()
        && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
      // package-info.java hack
      final List<TranslatingCompiler.OutputItem> outputs =
          new ArrayList<TranslatingCompiler.OutputItem>();
      ApplicationManager.getApplication()
          .runReadAction(
              new Runnable() {
                public void run() {
                  for (final VirtualFile file : myFilesToCompile) {
                    if (PACKAGE_ANNOTATION_FILE_NAME.equals(file.getName())
                        && !myProcessedPackageInfos.contains(file)) {
                      outputs.add(new OutputItemImpl(file));
                    }
                  }
                }
              });
      if (!outputs.isEmpty()) {
        mySink.add(null, outputs, VirtualFile.EMPTY_ARRAY);
      }
    }
  }
    private void processPath(FileObject fileObject, Project project)
        throws CacheCorruptedException {
      File file = fileObject.getFile();
      final String path = file.getPath();
      try {
        if (CompilerManager.MAKE_ENABLED) {
          byte[] fileContent = fileObject.getContent();
          // the file is assumed to exist!
          final JavaDependencyCache dependencyCache =
              myCompileContext.getDependencyCache().findChild(JavaDependencyCache.class);
          final int newClassQName = dependencyCache.reparseClassFile(file, fileContent);
          final Cache newClassesCache = dependencyCache.getNewClassesCache();
          final String sourceFileName = newClassesCache.getSourceFileName(newClassQName);
          final String qName = dependencyCache.resolve(newClassQName);
          String relativePathToSource =
              "/" + JavaMakeUtil.createRelativePathToSource(qName, sourceFileName);
          putName(sourceFileName, newClassQName, relativePathToSource, path);
          boolean haveToInstrument =
              myAddNotNullAssertions
                  && hasNotNullAnnotations(
                      newClassesCache, dependencyCache.getSymbolTable(), newClassQName, project);

          if (haveToInstrument) {
            try {
              ClassReader reader = new ClassReader(fileContent, 0, fileContent.length);
              ClassWriter writer = new PsiClassWriter(myProject, myIsJdk16);

              if (NotNullVerifyingInstrumenter.processClassFile(reader, writer)) {
                fileObject = new FileObject(file, writer.toByteArray());
              }
            } catch (Exception ignored) {
              LOG.info(ignored);
            }
          }

          fileObject.save();
        } else {
          final String _path = FileUtil.toSystemIndependentName(path);
          final int dollarIndex = _path.indexOf('$');
          final int tailIndex = dollarIndex >= 0 ? dollarIndex : _path.length() - ".class".length();
          final int slashIndex = _path.lastIndexOf('/');
          final String sourceFileName = _path.substring(slashIndex + 1, tailIndex) + ".java";
          String relativePathToSource = _path.substring(myOutputDir.length(), tailIndex) + ".java";
          putName(
              sourceFileName,
              0 /*doesn't matter here*/,
              relativePathToSource.startsWith("/")
                  ? relativePathToSource
                  : "/" + relativePathToSource,
              path);
        }
      } catch (ClsFormatException e) {
        final String m = e.getMessage();
        String message =
            CompilerBundle.message(
                "error.bad.class.file.format", StringUtil.isEmpty(m) ? path : m + "\n" + path);
        myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
        LOG.info(e);
      } catch (IOException e) {
        myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
        LOG.info(e);
      } finally {
        myStatistics.incClassesCount();
        updateStatistics();
      }
    }