class ScoreDistributions {

  public static ScoreDistribution merge(Collection<? extends ScoreDistribution> distributions) {
    if (distributions.isEmpty()) {
      throw new CannotMergeScoreDistributions("Cannot merge zero ScoreDistributions objects.");
    }
    if (distributions.stream().map(ScoreDistribution::getNumTerms).collect(Collectors.toSet()).size() != 1) {
      throw new CannotMergeScoreDistributions("Different numbers of terms used for precomputation");
    }

    Map<TermId, ObjectScoreDistribution> mapping = new HashMap<>();
    for (ScoreDistribution d : distributions) {
      for (TermId objectId : d.getObjectIds()) {
        final ObjectScoreDistribution dist = d.getObjectScoreDistribution(objectId);
        if (mapping.containsKey(objectId)) {
          throw new CannotMergeScoreDistributions("Duplicate object ID " + objectId + " detected");
        } else {
          mapping.put(objectId, dist);
        }
      }
    }

    return new ScoreDistribution(distributions.stream().findAny().get().getNumTerms(), mapping);
  }

}