CrossSpeciesPhenotypeMatcher implements PhenotypeMatcher { List<PhenotypeMatch> calculateBestForwardAndReciprocalMatches(List<String> modelPhenotypes) { List<String> matchedModelPhenotypeIds = modelPhenotypes.stream() .filter(matchedOrganismPhenotypeIds::contains) .collect(toList()); List<PhenotypeMatch> forwardMatches = matchedQueryPhenotypeIds.stream() .map(hp -> matchedModelPhenotypeIds.stream() .map(mp -> String.join("", hp, mp)) .map(mappedTerms::get) .filter(Objects::nonNull) .max(comparingDouble(PhenotypeMatch::getScore))) .filter(Optional::isPresent) .map(Optional::get) .collect(toList()); List<PhenotypeMatch> reciprocalMatches = matchedModelPhenotypeIds.stream() .map(mp -> matchedQueryPhenotypeIds.stream() .map(hp -> String.join("", hp, mp)) .map(mappedTerms::get) .filter(Objects::nonNull) .max(comparingDouble(PhenotypeMatch::getScore))) .filter(Optional::isPresent) .map(Optional::get) .collect(toList()); return Stream.concat(forwardMatches.stream(), reciprocalMatches.stream()) .collect(ImmutableList.toImmutableList()); } private  CrossSpeciesPhenotypeMatcher(QueryPhenotypeMatch queryPhenotypeMatch); @Override Organism getOrganism(); @Override List<PhenotypeTerm> getQueryTerms(); @Override Map<PhenotypeTerm, Set<PhenotypeMatch>> getTermPhenotypeMatches(); @Override Set<PhenotypeMatch> getBestPhenotypeMatches(); @Override QueryPhenotypeMatch getQueryPhenotypeMatch(); @Override PhenodigmMatchRawScore matchPhenotypeIds(List<String> modelPhenotypes); @Override boolean equals(Object o); @Override int hashCode(); @Override String toString();  }
@Test public void testGetBestForwardAndReciprocalMatchesReturnsEmptyListFromEmptyQuery() throws Exception { assertThat(instance.calculateBestForwardAndReciprocalMatches(Collections.emptyList()), equalTo(Collections.emptyList())); }