/** @should return patient data for each obs in the passed context */
  @Override
  public EvaluatedObsData evaluate(
      ObsDataDefinition definition, EvaluationContext obsEvaluationContext)
      throws EvaluationException {

    DataSetQueryService dqs = Context.getService(DataSetQueryService.class);
    EvaluatedObsData c = new EvaluatedObsData(definition, obsEvaluationContext);

    // create a map of obs ids -> patient ids (note assumption that personId = patientId)
    Set<Integer> obsIds = ObsDataUtil.getObsIdsForContext(obsEvaluationContext, true);
    Map<Integer, Integer> convertedIds =
        dqs.convertData(Person.class, "personId", null, Obs.class, "person.personId", obsIds);

    // create a new (patient) evaluation context using the retrieved ids
    EvaluationContext patientEvaluationContext = new EvaluationContext();
    patientEvaluationContext.setBaseCohort(new Cohort(convertedIds.values()));

    // evaluate the joined definition via this patient context
    PatientToObsDataDefinition def = (PatientToObsDataDefinition) definition;
    EvaluatedPatientData pd =
        Context.getService(PatientDataService.class)
            .evaluate(def.getJoinedDefinition(), patientEvaluationContext);

    // now create the result set by mapping the results in the patient data set to obs ids
    for (Integer obsId : obsIds) {
      c.addData(obsId, pd.getData().get(convertedIds.get(obsId)));
    }
    return c;
  }