protected void doMarshal(
      SigAndDataObjsPropertiesData properties, Node qualifyingPropsNode, TXml xmlProps)
      throws MarshalException {
    if (properties.isEmpty()) return;

    Collection<PropertyDataObject> unknownSigProps = null;
    if (!properties.getSigProps().isEmpty()) {
      prepareSigProps(xmlProps);
      unknownSigProps = convert(properties.getSigProps(), xmlProps);
    }

    Collection<PropertyDataObject> unknownDataObjProps = null;
    if (!properties.getDataObjProps().isEmpty()) {
      prepareDataObjsProps(xmlProps);
      unknownDataObjProps = convert(properties.getDataObjProps(), xmlProps);
    }

    if (propsNotAlreadyPresent(qualifyingPropsNode))
      // If the QualifyingProperties node doesn't already have an element
      // for the current type of properties, do a JAXB marshalling into it.
      doJAXBMarshalling(qualifyingPropsNode, xmlProps);
    else {
      // If it has, marshall into a temp node and transfer the resulting
      // nodes into the appropriate QualifyingProperties children.
      Node tempNode =
          DOMHelper.createElement(
              qualifyingPropsNode.getOwnerDocument(), "temp", null, QualifyingProperty.XADES_XMLNS);
      // - A little work around to inherit the namespace node defined in
      //   the document. Its just a matter of style.
      qualifyingPropsNode.appendChild(tempNode);
      doJAXBMarshalling(tempNode, xmlProps);
      qualifyingPropsNode.removeChild(tempNode);
      transferProperties(qualifyingPropsNode, tempNode);
    }

    // The top-most XML element for the current type of properties.
    Element topMostPropsElem =
        DOMHelper.getFirstDescendant(
            (Element) qualifyingPropsNode, QualifyingProperty.XADES_XMLNS, propsElemName);

    if (!CollectionUtils.nullOrEmpty(unknownSigProps))
      marshallUnknownProps(unknownSigProps, DOMHelper.getFirstChildElement(topMostPropsElem));
    if (!CollectionUtils.nullOrEmpty(unknownDataObjProps))
      marshallUnknownProps(unknownDataObjProps, DOMHelper.getLastChildElement(topMostPropsElem));
  }
  private Collection<PropertyDataObject> convert(
      Collection<PropertyDataObject> props, TXml xmlProps) throws MarshalException {
    Collection<PropertyDataObject> unknownProps = null;

    // Convert each property to the corresponding JAXB object. Each converter
    // will add the corresponding object to the tree.
    // If a converter is not found, it means that the property is unknown in
    // this version of XAdES; it will be converted afterwards.
    QualifyingPropertyDataToXmlConverter<TXml> conv;
    for (PropertyDataObject p : props) {
      conv = this.converters.get(p.getClass());
      if (null == conv) {
        unknownProps = CollectionUtils.newIfNull(unknownProps, 1);
        unknownProps.add(p);
      } else conv.convertIntoObjectTree(p, xmlProps);
    }
    return unknownProps;
  }