private static Map<String, String> buildClassToSourceMap(
     ModuleChunk chunk,
     CompileContext context,
     Set<String> toCompilePaths,
     String moduleOutputPath)
     throws IOException {
   final Map<String, String> class2Src = new HashMap<String, String>();
   for (Module module : chunk.getModules()) {
     final String moduleName = module.getName().toLowerCase(Locale.US);
     final SourceToOutputMapping srcToOut =
         context.getDataManager().getSourceToOutputMap(moduleName, context.isCompilingTests());
     for (String src : srcToOut.getKeys()) {
       if (!toCompilePaths.contains(src) && isGroovyFile(src)) {
         final Collection<String> outs = srcToOut.getState(src);
         if (outs != null) {
           for (String out : outs) {
             if (out.endsWith(".class") && out.startsWith(moduleOutputPath)) {
               final String className =
                   out.substring(moduleOutputPath.length(), out.length() - ".class".length())
                       .replace('/', '.');
               class2Src.put(className, src);
             }
           }
         }
       }
     }
   }
   return class2Src;
 }
    public BuildStatus build(final Collection<Module> modules, final Flags flags) {
      boolean incremental = flags.incremental();
      final List<ModuleChunk> chunks = myProjectBuilder.getChunks(flags.tests()).getChunkList();

      for (final ModuleChunk c : chunks) {
        final Set<Module> chunkModules = c.getElements();

        if (!DefaultGroovyMethods.intersect(modules, chunkModules).isEmpty()) {
          final Set<String> removedSources = new HashSet<String>();

          if (incremental) {
            final Set<String> chunkSources = new HashSet<String>();
            final Set<String> outdatedSources = new HashSet<String>();

            for (Module m : chunkModules) {
              final ModuleWrapper mw = getModule(m.getName());

              outdatedSources.addAll(mw.getOutdatedFiles(flags.tests()));
              chunkSources.addAll(mw.getSources(flags.tests()));
              removedSources.addAll(mw.getRemovedFiles(flags.tests()));
            }

            final BuildStatus result =
                iterativeCompile(c, chunkSources, outdatedSources, removedSources, flags);

            incremental = result == BuildStatus.INCREMENTAL;

            if (result == BuildStatus.FAILURE) {
              return result;
            }
          } else {
            new Logger(flags) {
              @Override
              public void log(PrintStream stream) {
                stream.println("Compiling chunk " + c.getName() + " non-incrementally.");
              }
            }.log();

            for (Module m : chunkModules) {
              final ModuleWrapper mw = getModule(m.getName());
              removedSources.addAll(flags.tests() ? mw.getRemovedTests() : mw.getRemovedSources());
            }

            final Set<Module> toClean = new HashSet<Module>();

            for (Module m : chunkModules) {
              if (!cleared.contains(m)) {
                toClean.add(m);
              }
            }

            if (!toClean.isEmpty() && !flags.tests()) {
              builder.clearChunk(new ModuleChunk(toClean), null, ProjectWrapper.this);
              cleared.addAll(toClean);
            }

            final Mappings delta = dependencyMapping.createDelta();
            final Callbacks.Backend deltaCallback = delta.getCallback();

            try {
              builder.buildChunk(c, flags.tests(), null, deltaCallback, ProjectWrapper.this);
            } catch (Exception e) {
              e.printStackTrace();
              return BuildStatus.FAILURE;
            }

            final Set<String> allFiles = new HashSet<String>();

            for (Module m : c.getElements()) {
              final ModuleWrapper module = getModule(m.getName());
              affectedFiles.removeAll(module.getSources(flags.tests()));
              allFiles.addAll(module.getSources(flags.tests()));
            }

            final Collection<File> files = new HashSet<File>();

            for (String f : allFiles) {
              files.add(new File(f));
            }

            dependencyMapping.integrate(delta, files, removedSources);

            for (Module m : chunkModules) {
              Reporter.reportBuildSuccess(m, flags.tests());
            }
          }
        }
      }

      return BuildStatus.INCREMENTAL;
    }
  private static boolean doResourcePackaging(
      @NotNull CompileContext context,
      @NotNull Collection<Module> modules,
      @NotNull Map<Module, AndroidFileSetState> resourcesStates,
      @NotNull Map<Module, AndroidFileSetState> assetsStates)
      throws IOException {
    boolean success = true;

    final File dataStorageRoot = context.getDataManager().getDataStorageRoot();
    final boolean releaseBuild = AndroidJpsUtil.isReleaseBuild(context);
    AndroidFileSetStorage resourcesStorage = null;
    AndroidFileSetStorage assetsStorage = null;

    try {
      final String resourcesStorageName =
          releaseBuild ? "resources_packaging_release" : "resources_packaging_dev";
      resourcesStorage = new AndroidFileSetStorage(dataStorageRoot, resourcesStorageName);

      final String assetsStorageName =
          releaseBuild ? "assets_packaging_release" : "assets_packaging_dev";
      assetsStorage = new AndroidFileSetStorage(dataStorageRoot, assetsStorageName);

      final Set<Module> modulesToUpdateState = new HashSet<Module>();

      for (Module module : modules) {
        final AndroidFacet facet = AndroidJpsUtil.getFacet(module);
        if (facet == null) {
          continue;
        }

        boolean updateState = true;

        if (!facet.isLibrary()
            && !(context.isMake()
                && checkUpToDate(module, resourcesStates, resourcesStorage)
                && checkUpToDate(module, assetsStates, assetsStorage))) {

          updateState = packageResources(facet, context);

          if (!updateState) {
            success = false;
          }
        }
        if (updateState) {
          modulesToUpdateState.add(module);
        }
      }

      for (Module module : modules) {
        final boolean updateState = modulesToUpdateState.contains(module);
        resourcesStorage.update(module.getName(), updateState ? resourcesStates.get(module) : null);
        assetsStorage.update(module.getName(), updateState ? assetsStates.get(module) : null);
      }
    } finally {
      if (resourcesStorage != null) {
        resourcesStorage.close();
      }

      if (assetsStorage != null) {
        assetsStorage.close();
      }
    }
    return success;
  }