private ProductPublicationStatus publishWorkProduct(
      EDXLDistribution edxl, DigestType digest, WorkProductDocument currentWorkProduct) {
    log.debug("Creating work product for HAVE message");
    ValidationUtil.validate(edxl, true);
    ValidationUtil.validate(digest, true);

    // Create a work product
    WorkProduct workProduct = new WorkProduct();
    workProduct.setProductType(HAVE_PRODUCT_TYPE);

    // If updating set the work product identification
    if (currentWorkProduct != null && currentWorkProduct.getWorkProduct() != null) {
      IdentificationType id =
          WorkProductHelper.getIdentificationElement(currentWorkProduct.getWorkProduct());
      if (id != null) {
        try {
          Integer version = Integer.parseInt(id.getVersion().getStringValue());
          workProduct.setProductVersion(version);
          workProduct.setChecksum(id.getChecksum().getStringValue());
          workProduct.setProductID(id.getIdentifier().getStringValue());
          workProduct.setProductType(id.getType().getStringValue());
          workProduct.setActive(id.getState() == StateType.ACTIVE);
        } catch (NumberFormatException e) {
          log.error("Error parsing version number to update HAVE message: " + e.getMessage());
        }
      } else {
        log.error("Cannot find WorkProductIdentification in matching HAVE message");
      }
    }

    //        workProduct.setProductID(wpIDBuffer.toString());
    EDXLDistributionDocument edxlDoc = EDXLDistributionDocument.Factory.newInstance();
    edxlDoc.addNewEDXLDistribution().set(edxl);
    workProduct.setProduct(edxlDoc.xmlText().getBytes());

    DigestDocument digestDoc = DigestDocument.Factory.newInstance();
    digestDoc.setDigest((DigestType) digest.copy());
    workProduct.setDigest(digestDoc);

    if (edxl.sizeOfContentObjectArray() > 0
        && edxl.getContentObjectArray(0).getIncidentID() != null) {
      workProduct
          .getAssociatedInterestGroupIDs()
          .add(edxl.getContentObjectArray(0).getIncidentID());
    }
    //        System.out.println(WorkProductHelper.toWorkProductXmlDocument(workProduct));

    // publish the work product
    ProductPublicationStatus status = workProductService.publishProduct(workProduct);

    return status;
  }
  @Override
  public WorkProductDocument findHAVEMessage(String distributionReference) {
    WorkProductDocument workProduct = WorkProductDocument.Factory.newInstance();
    workProduct.addNewWorkProduct();

    String[] elements = distributionReference.split(",");
    if (elements.length == 3) {
      StringBuffer sb = new StringBuffer();
      String DID = "/de:EDXLDistribution[de:distributionID/text()='";
      // /urn:EdxlDeRequest/de:EDXLDistribution[de:distributionID='DE_DISTRIBUTION_ID']
      sb.append(DID);
      sb.append(elements[0]);
      sb.append("']");
      // and /urn:EdxlDeRequest/de:EDXLDistribution[de:senderID='RMApplication1@core1']
      sb.append("and /de:EDXLDistribution[de:senderID='");
      sb.append(elements[1]);
      sb.append("']");
      // /de:EDXLDistribution[de:dateTimeSent='2010-11-11T13:42:36.890-05:00']
      sb.append("and /de:EDXLDistribution[de:dateTimeSent='");
      sb.append(elements[2]);
      sb.append("']");
      Map<String, String> namespaceMap = new HashMap<String, String>();
      namespaceMap.put("de", "urn:oasis:names:tc:emergency:EDXL:DE:1.0");
      try {
        List<WorkProduct> list =
            workProductService.getProductByTypeAndXQuery(
                HAVE_PRODUCT_TYPE, sb.toString(), namespaceMap);
        if (list.size() == 1) {
          WorkProduct wp = list.get(0);
          workProduct.setWorkProduct(WorkProductHelper.toWorkProduct(wp));
        }
      } catch (InvalidXpathException e) {
        log.error("Invalid XPath expression finding HAVE message: " + e.getMessage());
      }
    }

    return workProduct;
  }
  /**
   * Parse the content of the edxl message, determine the type of request, process the request
   * appropriately and send the message to each core that has a user in an explictAddress
   *
   * @param edxl the edxl
   * @return the edxl de response document
   * @throws IllegalArgumentException the illegal argument exception
   * @throws EmptyCoreNameListException the empty core name list exception
   * @throws SendMessageErrorException the send message error exception
   * @throws LocalCoreNotOnlineException the local core not online exception
   * @ssdd
   */
  @Transactional
  @Override
  public EdxlDeResponseDocument edxldeRequest(EDXLDistribution edxl)
      throws IllegalArgumentException, EmptyCoreNameListException, SendMessageErrorException,
          LocalCoreNotOnlineException {

    EdxlDeResponseDocument response = EdxlDeResponseDocument.Factory.newInstance();
    response.addNewEdxlDeResponse();

    // See if this is an update to a current work product.
    WorkProductDocument currentWorkProduct = null;
    if (edxl.sizeOfDistributionReferenceArray() > 0) {
      for (String dis : edxl.getDistributionReferenceArray()) {
        //            	String distributionRef = edxl.getDistributionReferenceArray(0);
        if (dis != null && !dis.isEmpty()) {
          currentWorkProduct = findHAVEMessage(dis);
          if (currentWorkProduct != null
              && currentWorkProduct.getWorkProduct() != null
              && currentWorkProduct.getWorkProduct().sizeOfStructuredPayloadArray() > 0) {
            break;
          }
        }
      }
    }

    // Check if we have the content we want else return null
    if (edxl.sizeOfContentObjectArray() > 0
        && edxl.getContentObjectArray(0).getXmlContent() != null
        && edxl.getContentObjectArray(0).getXmlContent().sizeOfEmbeddedXMLContentArray() > 0) {

      // Determine what type of RM message is in the embedded xml content
      QName qname = getContentsQName(edxl);

      if (qname != null) {
        if (qname == HAVE_RESOURCE_QNAME) {

          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          // Create the digest if we have an XSLT
          if (xsltSource == null) {
            response.getEdxlDeResponse().setErrorExists(false);
            response
                .getEdxlDeResponse()
                .setErrorString("Cannot find the HAVE Digest XSLT" + xsltFilePath);
            log.warn("HAVE message not digested because XSLT is missing");
          } else {
            baos = createDigest(edxl, baos);
          }

          try {
            DigestDocument digestDoc = DigestDocument.Factory.newInstance();
            if (baos.size() > 0) {
              // DigestDocument d = DigestDocument.Factory.parse(digest.getDomNode());
              ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
              digestDoc = DigestDocument.Factory.parse(bais);
              response.getEdxlDeResponse().addNewDigest().set(digestDoc.getDigest());
              response.getEdxlDeResponse().setDigest(digestDoc.getDigest());
            } else {
              digestDoc.addNewDigest();
            }

            ProductPublicationStatus status =
                publishWorkProduct(edxl, digestDoc.getDigest(), currentWorkProduct);
            if (status.getStatus() == ProductPublicationStatus.SuccessStatus) {
              response.getEdxlDeResponse().setErrorExists(false);
            } else if (status.getStatus() == ProductPublicationStatus.PendingStatus) {
              response.getEdxlDeResponse().setErrorExists(false);
              response.getEdxlDeResponse().setErrorString("Product publication is pending");
            } else {
              response.getEdxlDeResponse().setErrorExists(true);
              response
                  .getEdxlDeResponse()
                  .setErrorString("Product publication status was: " + status.getStatus());
            }
          } catch (XmlException e) {
            log.error("Failed parsing digest: " + e.getMessage());
          } catch (IOException e) {
            log.error("Failed parsing digest: " + e.getMessage());
          }
        }

        // send the message
        log.debug("Sending HAVE message ");
        sendEdxlDeMessage(edxl);

        return response;
      } else {
        log.error("HAVE is missing content from: " + edxl);
        response.getEdxlDeResponse().setErrorExists(true);
        response.getEdxlDeResponse().setErrorString("EDXL-HAVE Content Missing");
        return response;
      }

    } else {
      return null;
    }
  }