docs: public Optional<FMeasureInfo> score(final Iterable<? extends Iterable<?>> predicted,
        final Iterable<? extends Iterable<?>> gold) {
      final List<Set<Object>> predictedAsSets = CorefScorerUtils.toSets(predicted);
      final List<Set<Object>> goldAsSets = CorefScorerUtils.toSets(gold);
  
      final Map<Object, Set<Object>> predictedItemToGroup =
          CollectionUtils.makeElementsToContainersMap(predictedAsSets);
      final Map<Object, Set<Object>> goldItemToGroup =
          CollectionUtils.makeElementsToContainersMap(goldAsSets);
  
      CorefScorerUtils.checkPartitionsOverSameElements(predictedItemToGroup.keySet(),
          goldItemToGroup.keySet());
  
      final Optional<Float> recall =
          mucScoreComponent(goldAsSets, predictedAsSets, predictedItemToGroup);
      final Optional<Float> precision =
          mucScoreComponent(predictedAsSets, goldAsSets, goldItemToGroup);
  
      if (recall.isPresent() && precision.isPresent()) {
        // why are these floats?
        return Optional.<FMeasureInfo>of(new PrecisionRecallPair(precision.get(), recall.get()));
      } else {
        return Optional.absent();
      }
    }