@Override
  protected void doFullTaskAction() {
    // this is full run, clean the previous output
    File destinationDir = getOutputDir();
    emptyFolder(destinationDir);

    List<ResourceSet> resourceSets = getInputResourceSets();

    // create a new merger and populate it with the sets.
    ResourceMerger merger = new ResourceMerger();

    try {
      for (ResourceSet resourceSet : resourceSets) {
        resourceSet.setNormalizeResources(normalizeResources);
        // set needs to be loaded.
        resourceSet.loadFromFiles(getILogger());
        merger.addDataSet(resourceSet);
      }

      // get the merged set and write it down.
      MergedResourceWriter writer =
          new MergedResourceWriter(
              destinationDir, getCruncher(), getCrunchPng(), getProcess9Patch(), getPublicFile());
      writer.setInsertSourceMarkers(getInsertSourceMarkers());

      merger.mergeData(writer, false /*doCleanUp*/);

      // No exception? Write the known state.
      merger.writeBlobTo(getIncrementalFolder(), writer);
    } catch (MergingException e) {
      System.out.println(e.getMessage());
      merger.cleanBlob(getIncrementalFolder());
      throw new ResourceException(e.getMessage(), e);
    }
  }
  @Override
  protected void doIncrementalTaskAction(Map<File, FileStatus> changedInputs) {
    // create a merger and load the known state.
    ResourceMerger merger = new ResourceMerger();
    try {
      if (!merger.loadFromBlob(getIncrementalFolder(), true /*incrementalState*/)) {
        doFullTaskAction();
        return;
      }

      // compare the known state to the current sets to detect incompatibility.
      // This is in case there's a change that's too hard to do incrementally. In this case
      // we'll simply revert to full build.
      List<ResourceSet> resourceSets = getInputResourceSets();
      for (ResourceSet resourceSet : resourceSets) {
        resourceSet.setNormalizeResources(normalizeResources);
      }

      if (!merger.checkValidUpdate(resourceSets)) {
        getLogger().info("Changed Resource sets: full task run!");
        doFullTaskAction();
        return;
      }

      // The incremental process is the following:
      // Loop on all the changed files, find which ResourceSet it belongs to, then ask
      // the resource set to update itself with the new file.
      for (Map.Entry<File, FileStatus> entry : changedInputs.entrySet()) {
        File changedFile = entry.getKey();

        merger.findDataSetContaining(changedFile, fileValidity);
        if (fileValidity.getStatus() == FileValidity.FileStatus.UNKNOWN_FILE) {
          doFullTaskAction();
          return;
        } else if (fileValidity.getStatus() == FileValidity.FileStatus.VALID_FILE) {
          if (!fileValidity
              .getDataSet()
              .updateWith(
                  fileValidity.getSourceFile(), changedFile, entry.getValue(), getILogger())) {
            getLogger()
                .info(String.format("Failed to process %s event! Full task run", entry.getValue()));
            doFullTaskAction();
            return;
          }
        }
      }

      MergedResourceWriter writer =
          new MergedResourceWriter(
              getOutputDir(), getCruncher(), getCrunchPng(), getProcess9Patch(), getPublicFile());
      writer.setInsertSourceMarkers(getInsertSourceMarkers());
      merger.mergeData(writer, false /*doCleanUp*/);
      // No exception? Write the known state.
      merger.writeBlobTo(getIncrementalFolder(), writer);
    } catch (MergingException e) {
      merger.cleanBlob(getIncrementalFolder());
      throw new ResourceException(e.getMessage(), e);
    } finally {
      // some clean up after the task to help multi variant/module builds.
      fileValidity.clear();
    }
  }