private Message doProcess(Message theArg0) throws HL7Exception, ApplicationException {
      String encodedMessage = theArg0.encode();

      Terser terser = new Terser(theArg0);
      String msgType = terser.get("/MSH-9-1");
      String msgTrigger = terser.get("/MSH-9-2");
      MSH msh = (MSH) theArg0.get("MSH");

      ourLog.info("Message is of type " + msgType + "^" + msgTrigger);
      List<Failure> failures;

      try {
        String msgSourceOrg = terser.get("/MSH-3-1");
        String sourceOrg =
            myContributorConfig.getContributorConfig().getNameOfHspId9004(msgSourceOrg);
        ourLog.info("Sending organization from message is {} - {}", msgSourceOrg, sourceOrg);
      } catch (Exception e) {
        // ignore
      }

      Converter converter;
      try {
        converter = new Converter(true);
      } catch (JAXBException e2) {
        ourLog.error("Failed to convert message: Could not initialize converter", e2);
        throw new HL7Exception(e2);
      }

      String outcome = null;
      if ("ORU".equals(msgType) && "R01".equals(msgTrigger)) {
        final ORU_R01 oru = (ORU_R01) theArg0;
        final List<ClinicalDocumentGroup> documents = converter.convertClinicalDocument(oru);
        try {
          outcome =
              "ORU^R01 message evaluated (containing " + documents.size() + " documents/results)";
          //					outcome = Persister.persist(documents);
        } catch (final Exception e1) {
          throw new HL7Exception(e1);
        }
      } else if ("ADT".equals(msgType)) {
        ADT_A01 adt = new ADT_A01();
        adt.setParser(myParser);
        adt.parse(encodedMessage);
        PatientWithVisits pwv = converter.convertPatientWithVisits(adt);
        try {
          if (pwv != null) {
            outcome = "ADT^" + msgTrigger + " message evaluated";
            //						outcome = Persister.persist(pwv);
          } else {
            outcome = PROCESSING_FAILED_OUTCOME;
          }
        } catch (final Exception e1) {
          throw new HL7Exception(e1);
        }
      } else if ("RDE".equals(msgType) && "O11".equals(msgTrigger)) {
        RDE_O11 rde = new RDE_O11();
        rde.setParser(myParser);
        rde.parse(encodedMessage);
        List<MedicationOrder> medOrders = converter.convertMedicationOrder(rde);
        try {
          outcome =
              "RDE^O11 message evaluated (containing " + medOrders.size() + " medication orders)";
          //					outcome = Persister.persistMedicationOrders(medOrders);
        } catch (final Exception e1) {
          throw new HL7Exception(e1);
        }
      } else if ("RAS".equals(msgType) && "O17".equals(msgTrigger)) {
        RAS_O17 ras = new RAS_O17();
        ras.setParser(myParser);
        ras.parse(encodedMessage);
        List<MedicationOrderWithAdmins> medOrdersWithAdmins = converter.convertMedicationAdmin(ras);
        try {
          outcome =
              "RAS^O17 message evaluated (containing administration data for "
                  + medOrdersWithAdmins.size()
                  + " medication orders)";
          //					outcome = Persister.persistMedicationAdmins(medOrdersWithAdmins);
        } catch (final Exception e1) {
          throw new HL7Exception(e1);
        }
      } else {

        /*
         * Note: If adding processors for additional message types, make
         * sure to update the description for F098!!
         */

        converter.validateMsh(msh);
        converter.addFailure("/MSH-9", FailureCode.F098, msgType + "^" + msgTrigger);
        outcome = PROCESSING_FAILED_OUTCOME;
      }

      if (StringUtils.isBlank(outcome)) {
        outcome = PROCESSING_FAILED_OUTCOME;
      }

      // These are determined from the IDs in the message
      SendingSystem sendingSystem = converter.getSendingSystem();
      Contributor contributor = converter.getContributorConfig();

      //			if (contributor == null) {
      //				contributor = myContributor;
      //			} else if (contributor != myContributor) {
      //				converter.addFailure("MSH-3-1", FailureCode.F112,
      // msh.getMsh3_SendingApplication().getHd1_NamespaceID().getValue());
      //				contributor = myContributor;
      //			}

      if (sendingSystem == null) {
        throw new ApplicationException(
            "Failed to determine sender from message. Please check MSH-3 value");
      }

      //			if (sendingSystem == null ||
      // contributor.getSendingSystem9008WithOid(sendingSystem.getCode()) == null) {
      //				converter.addFailure("MSH-3-2", FailureCode.F113,
      // msh.getMsh3_SendingApplication().getHd2_UniversalID().getValue());
      //				sendingSystem = contributor.getSendingSystem().get(0);
      //				ourLog.info("Defaulting to first sending system {} because MSH-3-2 was {}",
      // sendingSystem.getDescription(),
      // msh.getMsh3_SendingApplication().getHd2_UniversalID().getValue());
      //			}

      ourLog.info(
          "Converted message from {} - {}", contributor.getName(), sendingSystem.getDescription());

      String orgId = sendingSystem.getManagementConsoleOrgId();
      if (StringUtils.isBlank(orgId)) {
        orgId = contributor.getManagementConsoleOrgId();
      }

      final CanonicalHl7V2Message canon =
          AbstractPojo.createNewCanonicalMessageHl7V2(
              encodedMessage,
              orgId,
              sendingSystem.getManagementConsoleSystemId(),
              Listener.INTERFACE_ID,
              MessagePhase.INCOMING,
              Listener.class,
              java.util.logging.Logger.getLogger(Listener.class.getName()));
      failures = converter.getFailures();
      if (failures.size() > 0) {

        String problemDescription = createHtmlProblemDescription(converter);

        if (problemDescription.length() > 0) {
          canon.setValidationOutcomeDescription(problemDescription);
        }

        ourLog.info("Message has {} failures", converter.getFailures().size());

      } else {

        ourLog.info("Message has no validation failures! Outstanding.");
        canon.setValidationOutcomeDescription("No issues");
      }

      if (outcome != null) {
        canon.setValidationOutcomeDescription(
            canon.getValidationOutcomeDescription() + "<br>Outcome: " + outcome);
      } else {
        canon.setValidationOutcomeDescription(canon.getValidationOutcomeDescription());
      }

      // Journal for the source
      ourLog.info("Journalling message");
      final JournalMessageRequest request = new JournalMessageRequest();
      request.setCanonicalHl7V2Message(canon);
      try {
        AbstractPojo.tryToJournalMessage(myJournalSvc, request);
      } catch (InvalidInputException e) {
        ourLog.error("Failed to send message to journal", e);
        throw new HL7Exception("Failed to process message");
      } catch (final sail.wsdl.infrastructure.journalling.UnexpectedErrorException e) {
        ourLog.error("Failed to send message to dead letter", e);
        throw new HL7Exception("Failed to process message");
      } catch (Exception e) {
        ourLog.error("Failed to journal message. Moving on", e);
        StringWriter w = new StringWriter();
        JAXB.marshal(request, w);
        ourLog.error("Request was: " + w.toString());
      }

      // // Journal again for the destination
      // canon.setDestination(new OutboundInterface());
      // canon.getDestination().setBoxId(canon.getSource().getBoxId());
      // canon.getDestination().setDomainId(canon.getSource().getDomainId());
      // canon.getDestination().setInterfaceDirection("O");
      // canon.getDestination().setOrgId("SIMS");
      // canon.getDestination().setSystemId("CGTA_Interim_CDR");
      // canon.getDestination().setInterfaceId("All");
      // canon.setCurrentMessagePhase(MessagePhase.OUTGOING);
      // try {
      // myJournalSvc.journalMessage(request);
      // } catch (final InvalidInputException e) {
      // ourLog.error("Failed to send message to journal", e);
      // } catch (final
      // sail.wsdl.infrastructure.journalling.UnexpectedErrorException e)
      // {
      // ourLog.error("Failed to send message to dead letter", e);
      // }

      try {
        ACK ack = (ACK) theArg0.generateACK();

        for (final Failure next : converter.getFailures()) {
          ERR err = ack.getERR(ack.getERRReps());
          err.getErr1_ErrorCodeAndLocation(0).getEld1_SegmentID().setValue(next.getTerserPath());
          err.getErr3_HL7ErrorCode().getCwe1_Identifier().setValue(next.getFailureCode().name());
          err.getErr6_ApplicationErrorParameter(0).setValue(next.getFieldVal());
          err.getErr7_DiagnosticInformation().setValue(next.getMessage());
        }

        return ack;
      } catch (final IOException e) {
        throw new HL7Exception(e);
      }
    }