BiopsyMatcher { @NotNull public static MatchResult<BiopsyData> matchBiopsiesToTumorSamples(@NotNull String patientIdentifier, @NotNull List<SampleData> sequencedBiopsies, @NotNull List<BiopsyData> clinicalBiopsies) { List<BiopsyData> matchedBiopsies = Lists.newArrayList(); List<ValidationFinding> findings = Lists.newArrayList(); List<BiopsyData> remainingBiopsies = clinicalBiopsies; Collections.sort(remainingBiopsies); Collections.sort(sequencedBiopsies); if (clinicalBiopsies.size() < sequencedBiopsies.size()) { findings.add(biopsyMatchFinding(patientIdentifier, "Not enough clinical biopsy forms to match for every sequenced sample", "Clinical biopsies: " + clinicalBiopsies.size() + ", sequenced samples: " + sequencedBiopsies.size())); } for (SampleData sequencedBiopsy : sequencedBiopsies) { Map<Boolean, List<BiopsyData>> partitions = remainingBiopsies.stream() .collect(Collectors.partitioningBy(clinicalBiopsy -> isPossibleMatch(sequencedBiopsy, clinicalBiopsy))); List<BiopsyData> possibleMatches = partitions.get(true); if (possibleMatches.size() == 1 && possibleMatches.get(0).date() != null) { BiopsyData clinicalBiopsy = possibleMatches.get(0); matchedBiopsies.add(ImmutableBiopsyData.builder().from(clinicalBiopsy).sampleId(sequencedBiopsy.sampleId()).build()); if (hasMismatchOnSamplingDate(sequencedBiopsy, clinicalBiopsy) && !patientIdentifier.startsWith("WIDE")) { findings.add(biopsyMatchFinding(patientIdentifier, "Sampling date does not equal biopsy date in matched biopsy", "sampling date: " + sequencedBiopsy.samplingDate() + "; ecrf biopsy date: " + clinicalBiopsy.date())); } remainingBiopsies = partitions.get(false); } else if (!patientIdentifier.startsWith("WIDE")) { if (possibleMatches.size() == 0 || (possibleMatches.size() == 1 && possibleMatches.get(0).date() == null)) { findings.add(biopsyMatchFinding(patientIdentifier, "Could not match any clinical biopsy with sequenced sample.", "sample: " + sampleDataToString(sequencedBiopsy) + "; ecrf biopsies: " + clinicalBiopsies + ". match criteria: " + getMatchDateCriteria(sequencedBiopsy))); } else if (possibleMatches.size() > 1) { findings.add(biopsyMatchFinding(patientIdentifier, "More than 1 possible clinical biopsy match for sequenced sample.", "sample: " + sampleDataToString(sequencedBiopsy) + "; ecrf biopsies: " + clinicalBiopsies + ". match criteria: " + getMatchDateCriteria(sequencedBiopsy))); } else { findings.add(biopsyMatchFinding(patientIdentifier, "Undetermined match issue in biopsy matcher", "sample: " + sampleDataToString(sequencedBiopsy))); } } } matchedBiopsies.addAll(remainingBiopsies); return new MatchResult<>(matchedBiopsies, findings); } private  BiopsyMatcher(); @NotNull static MatchResult<BiopsyData> matchBiopsiesToTumorSamples(@NotNull String patientIdentifier,
            @NotNull List<SampleData> sequencedBiopsies, @NotNull List<BiopsyData> clinicalBiopsies);  }
@Test public void createFindingWhenNotEnoughClinicalBiopsies() { List<SampleData> sequencedBiopsies = Lists.newArrayList(SEQUENCED_BIOPSY_JUL); List<BiopsyData> clinicalBiopsies = Lists.newArrayList(); MatchResult<BiopsyData> matchedBiopsies = BiopsyMatcher.matchBiopsiesToTumorSamples("patient", sequencedBiopsies, clinicalBiopsies); assertEquals(2, matchedBiopsies.findings().size()); assertTrue(matchedBiopsies.findings().get(0).message().toLowerCase().contains("not enough clinical biopsy forms to match")); }