@Override
  protected Map<String, Object> getSubstitutions(EvaluationContext context) {

    Map<String, Object> m = new HashMap<String, Object>();
    m.put("encounterTypeIds", Arrays.asList(1, 2, 3, 4, 13));
    m.put("onOrBefore", context.getEvaluationDate());

    return m;
  }
  @Override
  public EvaluatedPersonData evaluate(PersonDataDefinition definition, EvaluationContext context)
      throws EvaluationException {

    FirstEncounterAtFacilityDataDefinition def =
        (FirstEncounterAtFacilityDataDefinition) definition;
    EvaluatedPersonData c = new EvaluatedPersonData(def, context);

    if (context.getBaseCohort() == null || context.getBaseCohort().isEmpty()) {
      return c;
    }

    // find the facility number
    MOHFacility facility = (MOHFacility) context.getParameterValue("facility");

    // fail quickly if the facility does not exist
    if (facility == null) {
      log.warn("No facility provided; returning empty data.");
      return c;
    }

    // use HQL to do our bidding
    String hql =
        "from Encounter"
            + " where voided=false"
            + " and patientId in (:patientIds)"
            + " and location in (:locationList)"
            + " and encounterDatetime <= :onOrBefore"
            + " order by encounterDatetime asc";

    Map<String, Object> m = new HashMap<String, Object>();
    m.put("patientIds", context.getBaseCohort());
    m.put("locationList", facility.getLocations());
    m.put("onOrBefore", context.getEvaluationDate());

    DataSetQueryService qs = Context.getService(DataSetQueryService.class);
    List<Object> queryResult = qs.executeHqlQuery(hql, m);

    ListMap<Integer, Encounter> encForPatients = new ListMap<Integer, Encounter>();
    for (Object o : queryResult) {
      Encounter enc = (Encounter) o;
      encForPatients.putInList(enc.getPatientId(), enc);
    }

    for (Integer pId : encForPatients.keySet()) {
      List<Encounter> l = encForPatients.get(pId);
      c.addData(pId, l.get(0));
    }

    return c;
  }
  /**
   * @should start on PCP_PROPHYLAXIS_STARTED with not null answer
   * @should not start on PCP_PROPHYLAXIS_STARTED with null answer
   * @should stop on REASON_PCP_PROPHYLAXIS_STOPPED with not null answer
   * @should not stop on REASON_PCP_PROPHYLAXIS_STOPPED with null answer
   * @should start on CURRENT_MEDICATIONS equal to TRIMETHOPRIM_AND_SULFAMETHOXAZOLE
   * @should not start on CURRENT_MEDICATIONS equal to something other than
   *     TRIMETHOPRIM_AND_SULFAMETHOXAZOLE
   * @should start on PATIENT_REPORTED_CURRENT_PCP_PROPHYLAXIS equal to
   *     TRIMETHOPRIM_AND_SULFAMETHOXAZOLE
   * @should not start on PATIENT_REPORTED_CURRENT_PCP_PROPHYLAXIS equal to something other than
   *     TRIMETHOPRIM_AND_SULFAMETHOXAZOLE
   */
  @Override
  public EvaluatedPersonData evaluate(
      final PersonDataDefinition definition, final EvaluationContext context)
      throws EvaluationException {
    EvaluatedPersonData data = new EvaluatedPersonData(definition, context);

    if (context.getBaseCohort().isEmpty()) return data;

    Map<String, Object> m = new HashMap<String, Object>();
    m.put("personIds", context.getBaseCohort());

    String sql =
        "select person_id, obs_datetime"
            + "  from obs"
            + "  where"
            + "    person_id in (:personIds)"
            + "    and ("
            + "      (concept_id = 1263 and value_coded is not null) "
            + "      or (concept_id in (1193, 1109) and value_coded = 916) "
            + "    )"
            + "    and voided = 0";

    ListMap<Integer, Date> mappedStartDates = makeDatesMapFromSQL(sql, m);

    sql =
        "select person_id, obs_datetime"
            + "  from obs"
            + "  where"
            + "    person_id in (:personIds)"
            + "    and ("
            + "      (concept_id in (1262, 1925) and value_coded is not null) "
            + "      or (concept_id = 1261 and value_coded = 1260) "
            + "    )"
            + "    and voided = 0";

    ListMap<Integer, Date> mappedStopDates = makeDatesMapFromSQL(sql, m);

    for (Integer memberId : context.getBaseCohort().getMemberIds()) {
      Set<Date> stopDates = safeFind(mappedStopDates, memberId);
      Set<Date> startDates = safeFind(mappedStartDates, memberId);
      String rangeInformation =
          buildRangeInformation(startDates, stopDates, context.getEvaluationDate());
      data.addData(memberId, rangeInformation);
    }

    return data;
  }