public void addDiff(
      Diff diff, List<FileDiff> fileDiffs, Multimap<Integer, DiffComment> fileIdToDiffComments) {

    Assert.isNotNull(diff, "diff may not be null");
    TaskAttribute diffsAttribute = taskData.getRoot().getAttribute(DIFFS.toString());
    TaskAttribute diffAttribute = diffsAttribute.createAttribute(PREFIX_DIFF + diff.getRevision());
    diffAttribute.setValue(String.valueOf(diff.getRevision()));
    taskData
        .getAttributeMapper()
        .setDateValue(diffAttribute.createAttribute(LAST_UPDATED.toString()), diff.getTimestamp());
    int totalPublicComments = 0;
    int totalDraftComments = 0;

    for (FileDiff fileDiff : fileDiffs) {

      Collection<DiffComment> diffComments = fileIdToDiffComments.get(fileDiff.getId());
      int draftComments = 0;
      int publicComments = 0;
      for (DiffComment diffComment : diffComments) {
        if (Boolean.FALSE.equals(diffComment.getPublic())) draftComments++;
        else publicComments++;
      }
      totalPublicComments += publicComments;
      totalDraftComments += draftComments;

      TaskAttribute fileDiffAttribute =
          diffAttribute.createAttribute(PREFIX_FILE + fileDiff.getId());
      fileDiffAttribute.setValue(String.valueOf(fileDiff.getId()));
      fileDiffAttribute.createAttribute(SOURCE_FILE.toString()).setValue(fileDiff.getSourceFile());
      fileDiffAttribute
          .createAttribute(DEST_FILE.toString())
          .setValue(fileDiff.getDestinationFile());
      fileDiffAttribute
          .createAttribute(SOURCE_REVISION.toString())
          .setValue(fileDiff.getSourceRevision());
      fileDiffAttribute
          .createAttribute(DEST_DETAIL.toString())
          .setValue(fileDiff.getDestinationDetail());
      fileDiffAttribute
          .createAttribute(NUM_PUBLIC_COMMENTS.toString())
          .setValue(String.valueOf(publicComments));
      fileDiffAttribute
          .createAttribute(NUM_DRAFT_COMMENTS.toString())
          .setValue(String.valueOf(draftComments));
    }

    diffAttribute
        .createAttribute(NUM_PUBLIC_COMMENTS.toString())
        .setValue(String.valueOf(totalPublicComments));
    diffAttribute
        .createAttribute(NUM_DRAFT_COMMENTS.toString())
        .setValue(String.valueOf(totalDraftComments));
  }
  public List<FileDiff> getFileDiffs(int diffRevisionId) {

    List<FileDiff> fileDiffs = new ArrayList<FileDiff>();

    for (TaskAttribute fileDiffAttribute : diff(diffRevisionId).getAttributes().values()) {

      if (!fileDiffAttribute.getId().startsWith(PREFIX_FILE)) continue;

      int fileDiffId = Integer.parseInt(fileDiffAttribute.getValue());
      final String sourcePath = fileDiffAttribute.getAttribute(SOURCE_FILE.toString()).getValue();
      final String sourceRevision =
          fileDiffAttribute.getAttribute(SOURCE_REVISION.toString()).getValue();
      final String destinationFile =
          fileDiffAttribute.getAttribute(DEST_FILE.toString()).getValue();
      final String destinationDetail =
          fileDiffAttribute.getAttribute(DEST_DETAIL.toString()).getValue();

      fileDiffs.add(
          new FileDiff(fileDiffId, sourcePath, sourceRevision, destinationFile, destinationDetail));
    }

    return fileDiffs;
  }