private static boolean runPngCaching(
      @NotNull CompileContext context,
      @NotNull Module module,
      @NotNull AndroidFileSetStorage storage,
      @Nullable AndroidFileSetState state)
      throws IOException {
    final AndroidFileSetState savedState = storage.getState(module.getName());
    if (context.isMake() && savedState != null && savedState.equalsTo(state)) {
      return true;
    }

    final AndroidFacet facet = AndroidJpsUtil.getFacet(module);
    if (facet == null) {
      return true;
    }

    context.processMessage(
        new CompilerMessage(
            BUILDER_NAME,
            BuildMessage.Kind.INFO,
            AndroidJpsBundle.message("android.jps.progress.res.caching", module.getName())));

    final File resourceDir = AndroidJpsUtil.getResourceDirForCompilationPath(facet);
    if (resourceDir == null) {
      return true;
    }

    final Pair<AndroidSdk, IAndroidTarget> pair =
        AndroidJpsUtil.getAndroidPlatform(module, context, BUILDER_NAME);
    if (pair == null) {
      return false;
    }

    final File resCacheDir = AndroidJpsUtil.getResourcesCacheDir(context, module);

    if (!resCacheDir.exists()) {
      if (!resCacheDir.mkdirs()) {
        context.processMessage(
            new CompilerMessage(
                BUILDER_NAME,
                BuildMessage.Kind.ERROR,
                "Cannot create directory " + resCacheDir.getPath()));
        return false;
      }
    }

    final IAndroidTarget target = pair.second;

    final Map<AndroidCompilerMessageKind, List<String>> messages =
        AndroidApt.crunch(
            target, Collections.singletonList(resourceDir.getPath()), resCacheDir.getPath());

    AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME);

    final boolean success = messages.get(AndroidCompilerMessageKind.ERROR).isEmpty();
    storage.update(module.getName(), success ? state : null);
    return success;
  }
  private static boolean doPackageResources(
      @NotNull final CompileContext context,
      @NotNull File manifestFile,
      @NotNull IAndroidTarget target,
      @NotNull String[] resourceDirPaths,
      @NotNull String[] assetsDirPaths,
      @NotNull String outputFilePath,
      boolean releasePackage) {
    try {
      final String outputPath = releasePackage ? outputFilePath + RELEASE_SUFFIX : outputFilePath;

      final IgnoredFilePatterns ignoredFilePatterns = context.getProject().getIgnoredFilePatterns();

      final Map<AndroidCompilerMessageKind, List<String>> messages =
          AndroidApt.packageResources(
              target,
              -1,
              manifestFile.getPath(),
              resourceDirPaths,
              assetsDirPaths,
              outputPath,
              null,
              !releasePackage,
              0,
              new FileFilter() {
                @Override
                public boolean accept(File pathname) {
                  return !ignoredFilePatterns.isIgnored(PathUtil.getFileName(pathname.getPath()));
                }
              });

      AndroidJpsUtil.addMessages(context, messages, BUILDER_NAME);
      return messages.get(AndroidCompilerMessageKind.ERROR).size() == 0;
    } catch (final IOException e) {
      AndroidJpsUtil.reportExceptionError(context, null, e, BUILDER_NAME);
      return false;
    }
  }