private static boolean doCaching(
      @NotNull CompileContext context,
      @NotNull Collection<Module> modules,
      @NotNull Map<Module, AndroidFileSetState> module2state)
      throws IOException {
    boolean success = true;
    final File dataStorageRoot = context.getDataManager().getDataStorageRoot();
    final AndroidFileSetStorage storage =
        new AndroidFileSetStorage(dataStorageRoot, "resource_caching");

    try {
      for (Module module : modules) {
        final AndroidFileSetState state = module2state.get(module);

        try {
          if (!runPngCaching(context, module, storage, state)) {
            success = false;
          }
        } catch (IOException e) {
          AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
        }
      }
    } finally {
      storage.close();
    }
    return success;
  }
  private static boolean doPackaging(
      @NotNull CompileContext context, @NotNull Collection<Module> modules) throws IOException {
    final boolean release = AndroidJpsUtil.isReleaseBuild(context);
    final File dataStorageRoot = context.getDataManager().getDataStorageRoot();

    boolean success = true;

    AndroidFileSetStorage apkFileSetStorage = null;
    AndroidApkBuilderConfigStateStorage apkBuilderConfigStateStorage = null;
    try {
      final String apkFileSetStorageName = "apk_builder_file_set" + (release ? "_release" : "_dev");
      apkFileSetStorage = new AndroidFileSetStorage(dataStorageRoot, apkFileSetStorageName);

      final String apkBuilderStateStorageName =
          "apk_builder_config" + (release ? "_release" : "_dev");
      apkBuilderConfigStateStorage =
          new AndroidApkBuilderConfigStateStorage(dataStorageRoot, apkBuilderStateStorageName);

      for (Module module : modules) {
        try {
          if (!doPackagingForModule(
              context, module, apkFileSetStorage, apkBuilderConfigStateStorage, release)) {
            success = false;
          }
        } catch (IOException e) {
          AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
          success = false;
        }
      }
    } finally {
      if (apkFileSetStorage != null) {
        apkFileSetStorage.close();
      }

      if (apkBuilderConfigStateStorage != null) {
        apkBuilderConfigStateStorage.close();
      }
    }

    return success;
  }
  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;
  }