@Test
  @Verifies(
      value = "should return encounter with all child objects voided according to schema",
      method = "voidEncounterByHtmlFormSchema")
  public void testVoidEncounterByHtmlFormSchema_shouldReturnEncounterVoided() throws Exception {
    executeDataSet(
        XML_DATASET_PATH + new TestUtil().getTestDatasetFilename(XML_REGRESSION_TEST_DATASET));
    Encounter e = new Encounter();
    e.setPatient(Context.getPatientService().getPatient(2));
    Date date = Context.getDateFormat().parse("01/02/2003");
    e.setDateCreated(new Date());
    e.setEncounterDatetime(date);
    e.setLocation(Context.getLocationService().getLocation(2));
    e.setProvider(Context.getPersonService().getPerson(502));

    // add a bunch of obs...
    TestUtil.addObs(e, 2474, Context.getConceptService().getConcept(656), date); // matches

    Form form = new Form();
    HtmlForm htmlform = new HtmlForm();
    htmlform.setForm(form);
    form.setEncounterType(new EncounterType());
    htmlform.setDateChanged(new Date());
    htmlform.setXmlData(
        new TestUtil()
            .loadXmlFromFile(
                XML_DATASET_PATH + "returnSectionsAndConceptsInSectionsTestFormWithGroups.xml"));
    HtmlFormEntryUtil.voidEncounterByHtmlFormSchema(e, htmlform, null);

    // this is going to test out the voided state of the obs in the encounter after processing:
    Assert.assertTrue(e.isVoided());
  }
  @Test
  @Verifies(
      value = "should return encounter with all child objects voided according to schema",
      method = "voidEncounterByHtmlFormSchema")
  public void testVoidEncounterByHtmlFormSchema_shouldHandleDrugOrderCorrectly() throws Exception {
    executeDataSet(
        XML_DATASET_PATH + new TestUtil().getTestDatasetFilename(XML_REGRESSION_TEST_DATASET));
    Encounter e = new Encounter();
    e.setPatient(Context.getPatientService().getPatient(2));
    Date date = Context.getDateFormat().parse("01/02/2003");
    e.setDateCreated(new Date());
    e.setEncounterDatetime(date);
    e.setLocation(Context.getLocationService().getLocation(2));
    e.setProvider(Context.getPersonService().getPerson(502));
    TestUtil.addObs(e, 1, 5000, date); // a matching obs

    DrugOrder dor = new DrugOrder();
    dor.setVoided(false);
    dor.setConcept(Context.getConceptService().getConcept(792));
    dor.setCreator(Context.getUserService().getUser(1));
    dor.setDateCreated(new Date());
    dor.setDiscontinued(false);
    dor.setDrug(Context.getConceptService().getDrug(2));
    dor.setOrderType(Context.getOrderService().getOrderType(1));
    dor.setPatient(Context.getPatientService().getPatient(2));
    dor.setStartDate(new Date());
    e.addOrder(dor);

    Context.getEncounterService().saveEncounter(e);

    Form form = new Form();
    HtmlForm htmlform = new HtmlForm();
    htmlform.setForm(form);
    form.setEncounterType(new EncounterType());
    htmlform.setDateChanged(new Date());
    htmlform.setXmlData(
        new TestUtil()
            .loadXmlFromFile(
                XML_DATASET_PATH + "returnSectionsAndConceptsInSectionsTestFormWithGroups.xml"));

    HtmlFormEntryUtil.voidEncounterByHtmlFormSchema(e, htmlform, "test void reason");

    // this is going to test out the voided state of the obs in the encounter after processing:
    // order was matched, so order was voided, and because that's the only thing in the encounter,
    // encounter was voided too.
    Assert.assertTrue(e.isVoided());
    Assert.assertTrue(e.getVoidReason().equals("test void reason"));
    for (Order o : e.getOrders()) {
      Assert.assertTrue(o.isVoided());
      Assert.assertTrue(o.getVoidReason().equals("test void reason"));
    }
    for (Obs o : e.getAllObs(true)) {
      Assert.assertTrue(o.getVoidReason().equals("test void reason"));
    }
  }
  @Test
  @Verifies(value = "should delete encounter correctly", method = "voidEncounterByHtmlFormSchema")
  public void testVoidEncounterByHtmlFormSchema_shouldDeleteEncounter() throws Exception {
    executeDataSet(
        XML_DATASET_PATH + new TestUtil().getTestDatasetFilename(XML_REGRESSION_TEST_DATASET));
    Encounter e = new Encounter();
    e.setPatient(Context.getPatientService().getPatient(2));
    Date date = Context.getDateFormat().parse("01/02/2003");
    e.setDateCreated(new Date());
    e.setEncounterDatetime(date);
    e.setLocation(Context.getLocationService().getLocation(2));
    e.setProvider(Context.getPersonService().getPerson(502));
    TestUtil.addObs(e, 3, 5000, date); // adding an un-matched, voided Obs
    for (Obs o : e.getAllObs(true)) {
      o.setVoided(true);
      o.setVoidedBy(Context.getUserService().getUser(1));
      o.setVoidReason("blah");
      o.setDateVoided(new Date());
    }

    // and adding a voided drug order
    DrugOrder dor = new DrugOrder();
    dor.setVoided(false);
    dor.setConcept(Context.getConceptService().getConcept(792));
    dor.setCreator(Context.getUserService().getUser(1));
    dor.setDateCreated(new Date());
    dor.setDiscontinued(false);
    dor.setDrug(Context.getConceptService().getDrug(2));
    dor.setOrderType(Context.getOrderService().getOrderType(1));
    dor.setPatient(Context.getPatientService().getPatient(2));
    dor.setVoided(true);
    dor.setVoidedBy(Context.getUserService().getUser(1));
    dor.setVoidReason("blah");
    dor.setDateVoided(new Date());
    dor.setStartDate(new Date());
    e.addOrder(dor);

    Context.getEncounterService().saveEncounter(e);

    Form form = new Form();
    HtmlForm htmlform = new HtmlForm();
    htmlform.setForm(form);
    form.setEncounterType(new EncounterType());
    htmlform.setDateChanged(new Date());
    htmlform.setXmlData(
        new TestUtil()
            .loadXmlFromFile(
                XML_DATASET_PATH + "returnSectionsAndConceptsInSectionsTestFormWithGroups.xml"));

    HtmlFormEntryUtil.voidEncounterByHtmlFormSchema(e, htmlform, null);

    // encounter had no non-voided objects, should be voided
    Assert.assertTrue(e.isVoided());
  }
  @Test
  @Verifies(
      value = "should return encounter with all child objects voided according to schema",
      method = "voidEncounterByHtmlFormSchema")
  public void testVoidEncounterByHtmlFormSchema_shouldHandleDrugOrderAndObsCorrectly()
      throws Exception {
    executeDataSet(
        XML_DATASET_PATH + new TestUtil().getTestDatasetFilename(XML_REGRESSION_TEST_DATASET));
    Encounter e = new Encounter();
    e.setPatient(Context.getPatientService().getPatient(2));
    Date date = Context.getDateFormat().parse("01/02/2003");
    e.setDateCreated(new Date());
    e.setEncounterDatetime(date);
    e.setLocation(Context.getLocationService().getLocation(2));
    e.setProvider(Context.getPersonService().getPerson(502));
    TestUtil.addObs(e, 3, 5000, date); // adding an un-matched Obs

    DrugOrder dor = new DrugOrder();
    dor.setVoided(false);
    dor.setConcept(Context.getConceptService().getConcept(792));
    dor.setCreator(Context.getUserService().getUser(1));
    dor.setDateCreated(new Date());
    dor.setDiscontinued(false);
    dor.setDrug(Context.getConceptService().getDrug(2));
    dor.setOrderType(Context.getOrderService().getOrderType(1));
    dor.setPatient(Context.getPatientService().getPatient(2));
    dor.setStartDate(new Date());
    e.addOrder(dor);

    Context.getEncounterService().saveEncounter(e);

    Form form = new Form();
    HtmlForm htmlform = new HtmlForm();
    htmlform.setForm(form);
    form.setEncounterType(new EncounterType());
    htmlform.setDateChanged(new Date());
    htmlform.setXmlData(
        new TestUtil()
            .loadXmlFromFile(
                XML_DATASET_PATH + "returnSectionsAndConceptsInSectionsTestFormWithGroups.xml"));

    HtmlFormEntryUtil.voidEncounterByHtmlFormSchema(e, htmlform, null);

    // order was matched, obs was not, so order should be voided, obs not, encounter not.
    Assert.assertTrue(!e.isVoided());
    for (Order o : e.getOrders()) {
      Assert.assertTrue(o.isVoided());
    }
    for (Obs o : e.getObs()) {
      Assert.assertTrue(!o.isVoided());
    }
  }
    /**
     *
     * Returns the encounter with the obs that aren't used when populating form are removed.
     * This *doesn't* save the encounter.
     * TODO: handle Orders?
     *
     * @param e
     * @param htmlform
     * @return
     * @throws Exception
     */
    public static Encounter trimEncounterToMatchForm(Encounter e, HtmlForm htmlform) throws Exception {

       //this should move existing obs from session to tag handlers.
        FormEntrySession session = new FormEntrySession(e.getPatient(), e, FormEntryContext.Mode.VIEW, htmlform, null); // session gets a null HttpSession
        session.getHtmlToDisplay();

        if (log.isDebugEnabled()){
            Map<Concept, List<Obs>>  map = session.getContext().getExistingObs();
            if (map != null){
                for (Map.Entry<Concept, List<Obs>> existingObs : map.entrySet()){
                    List<Obs> oList = existingObs.getValue();
                    for (Obs oInner : oList)
                        log.debug("Obs in existingObs " + existingObs.getKey() + " " + oInner.getConcept());
                }
            }
            Map<Obs, Set<Obs>> map2 = session.getContext().getExistingObsInGroups();
            if (map2 != null){
                for (Map.Entry<Obs, Set<Obs>> existingObsInGroups : map2.entrySet()){
                    Set<Obs> oList = existingObsInGroups.getValue();
                    for (Obs oInner : oList)
                        log.debug("Obs in existingObsInGroups " + existingObsInGroups.getKey().getConcept() + " " + oInner.getConcept());
                }
            }
        }
        Encounter ret = new Encounter();
        ret.setCreator(e.getCreator());
        ret.setEncounterDatetime(e.getEncounterDatetime());
        EncounterCompatibility.setProvider(ret, EncounterCompatibility.getProvider(e));
        ret.setLocation(e.getLocation());
        ret.setDateCreated(e.getDateCreated());
        ret.setPatient(e.getPatient());
        //renders new encounter unsave-able:
        ret.setEncounterId(e.getEncounterId());

        for (Obs oTest : e.getAllObs()){
            boolean found = false;
            if (session.getContext().getExistingObs() != null && !oTest.isObsGrouping()){
                List<Obs> obsList = session.getContext().getExistingObs().get(oTest.getConcept());
                if (obsList != null && obsList.size() > 0){
                    for (Obs o : obsList){
                        if (o.getObsId().equals(oTest.getObsId())){
                            found = true;
                            continue;
                        }
                    }
                }
            }
            if (!found && session.getContext().getExistingObsInGroups() != null){
                for (Map.Entry<Obs, Set<Obs>> mapEntry : session.getContext().getExistingObsInGroups().entrySet()){
                    if (mapEntry.getKey().equals(oTest)){
                        found = true;
                        continue;
                    } else {
                        Set<Obs> oSet = mapEntry.getValue();
                        //note: oSet.contains fails for some reason
                        for (Obs o:oSet){
                              if (o.getObsId().equals(oTest.getObsId())){
                                  found = true;
                                  continue;
                              }
                        }
                    }
                }
            }
            if (!found)
                ret.addObs(oTest);
        }
        session = null;
        return ret;
    }
  @Test
  @Verifies(
      value = "should return encounter with all child objects voided according to schema",
      method = "voidEncounterByHtmlFormSchema")
  public void testVoidEncounterByHtmlFormSchema_shouldReturnEncounterCorrectly() throws Exception {
    executeDataSet(
        XML_DATASET_PATH + new TestUtil().getTestDatasetFilename(XML_REGRESSION_TEST_DATASET));
    Encounter e = new Encounter();
    e.setPatient(Context.getPatientService().getPatient(2));
    Date date = Context.getDateFormat().parse("01/02/2003");
    e.setDateCreated(new Date());
    e.setEncounterDatetime(date);
    e.setLocation(Context.getLocationService().getLocation(2));
    e.setProvider(Context.getPersonService().getPerson(502));

    // add a bunch of obs...
    TestUtil.addObs(e, 2474, Context.getConceptService().getConcept(656), date); // matches
    TestUtil.addObs(e, 3017, Context.getConceptService().getConcept(767), date); // matches
    TestUtil.addObs(e, 3032, new Date(), date); // matches
    TestUtil.addObs(e, 1, 5000, date); //   matches
    TestUtil.addObs(e, 2, 5000, date); // not in form schema
    TestUtil.addObs(e, 3, 5000, date); // not in form schema
    TestUtil.addObs(e, 6, "blah blah", date); //   matches
    // 1004 is ANOTHER ALLERGY CONSTRUCT, 1005 is HYPER-ALLERGY CODED, 1001 is PENICILLIN
    TestUtil.addObsGroup(
        e,
        1004,
        new Date(),
        1005,
        Context.getConceptService().getConcept(1001),
        new Date()); // matches
    // 7 IS ALLERGY CONSTRUCT, 1000 IS ALLERGY CODED, 1003 IS OPENMRS
    TestUtil.addObsGroup(
        e,
        7,
        new Date(),
        1000,
        Context.getConceptService().getConcept(1003),
        new Date()); // matches
    TestUtil.addObsGroup(
        e,
        1000,
        new Date(),
        7,
        Context.getConceptService().getConcept(1003),
        new Date()); // does not match
    Context.getEncounterService().saveEncounter(e);

    Form form = new Form();
    HtmlForm htmlform = new HtmlForm();
    htmlform.setForm(form);
    form.setEncounterType(new EncounterType());
    htmlform.setDateChanged(new Date());
    htmlform.setXmlData(
        new TestUtil()
            .loadXmlFromFile(
                XML_DATASET_PATH + "returnSectionsAndConceptsInSectionsTestFormWithGroups.xml"));
    HtmlFormEntryUtil.voidEncounterByHtmlFormSchema(e, htmlform, null);

    // this is going to test out the voided state of the obs in the encounter after processing:
    Assert.assertTrue(!e.isVoided());
    for (Obs o : e.getAllObs(true)) {
      if (o.getConcept().getConceptId().equals(2474)) Assert.assertTrue(o.isVoided());
      if (o.getConcept().getConceptId().equals(3017)) Assert.assertTrue(o.isVoided());
      if (o.getConcept().getConceptId().equals(3032)) Assert.assertTrue(o.isVoided());
      if (o.getConcept().getConceptId().equals(1)) Assert.assertTrue(o.isVoided());
      if (o.getConcept().getConceptId().equals(2)) Assert.assertTrue(!o.isVoided()); // not matched
      if (o.getConcept().getConceptId().equals(3)) Assert.assertTrue(!o.isVoided()); // not matched
      if (o.getConcept().getConceptId().equals(6)) Assert.assertTrue(o.isVoided());
      if (o.getConcept().getConceptId().equals(1004)) Assert.assertTrue(o.isVoided());
      if (o.getConcept().getConceptId().equals(1005)) Assert.assertTrue(o.isVoided());

      // obsGroups
      if (o.getConcept().getConceptId().equals(7) && o.isObsGrouping())
        Assert.assertTrue(o.isVoided());
      if (o.getConcept().getConceptId().equals(7) && !o.isObsGrouping())
        Assert.assertTrue(!o.isVoided()); // not matched
      if (o.getConcept().getConceptId().equals(1000) && o.isObsGrouping())
        Assert.assertTrue(!o.isVoided()); // not matched
      if (o.getConcept().getConceptId().equals(1000) && !o.isObsGrouping())
        Assert.assertTrue(o.isVoided());
    }
  }