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;
  }
  private HashSet<String> getRecipientCores(EDXLDistribution edxl) {

    HashSet<String> cores = new HashSet<String>();
    if (edxl.sizeOfExplicitAddressArray() > 0) {
      // Find core name for each explicit address.
      for (ValueSchemeType type : edxl.getExplicitAddressArray()) {
        if (type.getExplicitAddressScheme().equals(CommunicationsService.UICDSCoreAddressScheme)) {
          for (String address : type.getExplicitAddressValueArray()) {
            cores.add(address);
          }
        }
      }
    }
    return cores;
  }
 public QName getContentsQName(EDXLDistribution edxl) {
   QName qname = null;
   XmlCursor c =
       edxl.getContentObjectArray(0).getXmlContent().getEmbeddedXMLContentArray(0).newCursor();
   try {
     if (c.toFirstChild()) {
       qname = c.getObject().schemaType().getOuterType().getDocumentElementName();
     }
   } catch (Exception e) {
     log.error("Error finding EDXL-DE content type: " + e.getMessage());
     log.error("From EDXL-DE: " + edxl.toString());
   } finally {
     c.dispose();
   }
   return qname;
 }
  public ByteArrayOutputStream createDigest(EDXLDistribution edxl, ByteArrayOutputStream baos) {
    // DigestType digest = DigestType.Factory.newInstance();
    // javax.xml.transform.Result result = new
    // javax.xml.transform.dom.DOMResult(digest.getDomNode());
    javax.xml.transform.Result result = new javax.xml.transform.stream.StreamResult(baos);

    try {
      javax.xml.transform.Source xmlSource =
          new javax.xml.transform.dom.DOMSource(edxl.getDomNode());
      transformer.transform(xmlSource, result);

    } catch (Throwable e) {
      log.error("Transformation failed: " + e.getMessage() + ".");
      e.printStackTrace();
    }
    return baos;
  }
  /**
   * 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;
    }
  }