@Override
  public EncounterQueryResult evaluate(EncounterQuery definition, EvaluationContext context)
      throws EvaluationException {
    context = ObjectUtil.nvl(context, new EvaluationContext());

    BasicEncounterQuery query = (BasicEncounterQuery) definition;
    EncounterQueryResult result = new EncounterQueryResult(query, context);

    Criteria criteria = sessionFactory.getCurrentSession().createCriteria(Encounter.class);
    criteria.setProjection(Projections.id());
    criteria.add(Restrictions.eq("voided", false));

    if (query.getOnOrAfter() != null) {
      criteria.add(Restrictions.ge("encounterDatetime", query.getOnOrAfter()));
    }
    if (query.getOnOrBefore() != null) {
      criteria.add(
          Restrictions.le(
              "encounterDatetime", DateUtil.getEndOfDayIfTimeExcluded(query.getOnOrBefore())));
    }

    if (context.getBaseCohort() != null) {
      if (context.getBaseCohort().size() == 0) {
        return result;
      } else {
        criteria.add(Restrictions.in("patient.id", context.getBaseCohort().getMemberIds()));
      }
    }
    if (context instanceof EncounterEvaluationContext) {
      EncounterIdSet baseEncounters = ((EncounterEvaluationContext) context).getBaseEncounters();
      if (baseEncounters != null) {
        if (baseEncounters.getSize() == 0) {
          return result;
        } else {
          criteria.add(Restrictions.in("id", baseEncounters.getMemberIds()));
        }
      }
    }

    for (Integer encounterId : ((List<Integer>) criteria.list())) {
      result.add(encounterId);
    }
    return result;
  }