/**
   * Compares the covariate report lists.
   *
   * @param diffs map where to annotate the difference.
   * @param other the argument collection to compare against.
   * @param thisRole the name for this argument collection that makes sense to the user.
   * @param otherRole the name for the other argument collection that makes sense to the end user.
   * @return <code>true</code> if a difference was found.
   */
  @Requires("diffs != null && other != null && thisRole != null && otherRole != null")
  private boolean compareRequestedCovariates(
      final Map<String, String> diffs,
      final RecalibrationArgumentCollection other,
      final String thisRole,
      final String otherRole) {

    final Set<String> beforeNames = new HashSet<>(this.COVARIATES.length);
    final Set<String> afterNames = new HashSet<>(other.COVARIATES.length);
    Utils.addAll(beforeNames, this.COVARIATES);
    Utils.addAll(afterNames, other.COVARIATES);
    final Set<String> intersect = new HashSet<>(Math.min(beforeNames.size(), afterNames.size()));
    intersect.addAll(beforeNames);
    intersect.retainAll(afterNames);

    String diffMessage = null;
    if (intersect.size()
        == 0) { // In practice this is not possible due to required covariates but...
      diffMessage =
          String.format(
              "There are no common covariates between '%s' and '%s'"
                  + " recalibrator reports. Covariates in '%s': {%s}. Covariates in '%s': {%s}.",
              thisRole,
              otherRole,
              thisRole,
              Utils.join(", ", this.COVARIATES),
              otherRole,
              Utils.join(",", other.COVARIATES));
    } else if (intersect.size() != beforeNames.size() || intersect.size() != afterNames.size()) {
      beforeNames.removeAll(intersect);
      afterNames.removeAll(intersect);
      diffMessage =
          String.format(
              "There are differences in the set of covariates requested in the"
                  + " '%s' and '%s' recalibrator reports. "
                  + " Exclusive to '%s': {%s}. Exclusive to '%s': {%s}.",
              thisRole,
              otherRole,
              thisRole,
              Utils.join(", ", beforeNames),
              otherRole,
              Utils.join(", ", afterNames));
    }
    if (diffMessage != null) {
      diffs.put("covariate", diffMessage);
      return true;
    } else {
      return false;
    }
  }