/// <summary>
        /// Complete the <paramref name="pmode" /> with the SMP metadata that is present in the <paramref name="smpMetaData" />
        /// <see cref="XmlDocument" />
        /// </summary>
        /// <param name="pmode">The <see cref="SendingProcessingMode" /> that must be decorated with the SMP metadata</param>
        /// <param name="smpMetaData">An XmlDocument that contains the SMP MetaData that has been received from an SMP server.</param>
        /// <returns>The completed <see cref="SendingProcessingMode" /></returns>
        public DynamicDiscoveryResult DecoratePModeWithSmpMetaData(SendingProcessingMode pmode, XmlDocument smpMetaData)
        {
            if (pmode == null)
            {
                throw new ArgumentNullException(nameof(pmode));
            }

            if (smpMetaData == null)
            {
                throw new ArgumentNullException(nameof(smpMetaData));
            }

            var smpResponse = AS4XmlSerializer.FromString <SmpConfiguration>(smpMetaData.OuterXml);

            if (smpResponse == null)
            {
                throw new ArgumentNullException(
                          nameof(smpResponse),
                          $@"SMP Response cannot be deserialized correctly to a SmpConfiguration model: {smpMetaData.OuterXml}");
            }

            OverridePushProtocolUrlWithTlsEnabling(pmode, smpResponse);
            OverrideEntireEncryption(pmode, smpResponse);
            OverrideToParty(pmode, smpResponse);
            OverrideCollaborationServiceAction(pmode, smpResponse);
            AddFinalRecipientToMessageProperties(pmode, smpResponse);

            return(DynamicDiscoveryResult.Create(pmode));
        }
        /// <summary>
        /// Complete the <paramref name="pmode"/> with the SMP metadata that is present in the <paramref name="smpMetaData"/> <see cref="XmlDocument"/>
        /// </summary>
        /// <param name="pmode"></param>
        /// <param name="smpMetaData"></param>
        /// <returns></returns>
        public DynamicDiscoveryResult DecoratePModeWithSmpMetaData(SendingProcessingMode pmode, XmlDocument smpMetaData)
        {
            if (pmode == null)
            {
                throw new ArgumentNullException(nameof(pmode));
            }

            if (smpMetaData == null)
            {
                throw new ArgumentNullException(nameof(smpMetaData));
            }

            XmlNode endpoint        = SelectServiceEndpointNode(smpMetaData);
            XmlNode certificateNode = endpoint.SelectSingleNode("*[local-name()='Certificate']");

            Logger.Debug($"Decorate SendingPMode {pmode.Id} with SMP response from ESens SMP Server");

            OverwritePushProtocolUrl(pmode, endpoint);
            DecorateMessageProperties(pmode, smpMetaData);
            OverwriteCollaborationServiceAction(pmode, smpMetaData);

            if (certificateNode != null)
            {
                OverwriteToParty(pmode, certificateNode);
                OverwriteEncryptionCertificate(pmode, certificateNode);
            }
            else
            {
                Logger.Trace("Don't override MessagePackaging.PartyInfo.ToParty because no <Certificate/> element found in SMP response");
                Logger.Trace("Don't override Encryption Certificate because no <Certificate/> element found in SMP response");
            }

            // TODO: should we specify to override the ToParty here also?
            return(DynamicDiscoveryResult.Create(pmode));
        }
        /// <summary>
        /// Complete the <paramref name="pmode"/> with the SMP metadata that is present in the <paramref name="smpMetaData"/> <see cref="XmlDocument"/>
        /// </summary>
        /// <param name="pmode">The <see cref="SendingProcessingMode"/> that must be decorated with the SMP metadata</param>
        /// <param name="smpMetaData">An XmlDocument that contains the SMP MetaData that has been received from an SMP server.</param>
        /// <returns>The completed <see cref="SendingProcessingMode"/></returns>
        public DynamicDiscoveryResult DecoratePModeWithSmpMetaData(SendingProcessingMode pmode, XmlDocument smpMetaData)
        {
            if (pmode == null)
            {
                throw new ArgumentNullException(nameof(pmode));
            }

            if (smpMetaData == null)
            {
                throw new ArgumentNullException(nameof(smpMetaData));
            }

            var ns = new XmlNamespaceManager(smpMetaData.NameTable);

            ns.AddNamespace("oasis", "http://docs.oasis-open.org/bdxr/ns/SMP/2016/05");

            XmlNode endpointNode = SelectEndpointNode(smpMetaData, ns);

            OverridePushConfigurationProtocolUrl(pmode, endpointNode, ns);
            OverrideMessageProperties(pmode, smpMetaData, ns);
            OverrideCollaborationAction(pmode, smpMetaData, ns);
            OverrideCollaborationService(pmode, smpMetaData, ns);

            XmlNode certificateNode = smpMetaData.SelectSingleNode("//oasis:Certificate", ns);

            if (certificateNode != null)
            {
                string certificateBinaries = certificateNode.InnerText.Replace(" ", "").Replace("\r\n", "");
                OverrideEncryptionCertificate(pmode, certificateBinaries);
                OverrideToParty(pmode, certificateBinaries);

                return(DynamicDiscoveryResult.Create(pmode, overrideToParty: true));
            }

            Logger.Trace("Don't override MessagePackaging.PartyInfo.ToParty because no <Certificate/> element found in SMP meta-data");
            Logger.Trace("Don't override Encryption Certificate because no <Certificate/> element found in SMP meta-data");

            return(DynamicDiscoveryResult.Create(pmode));
        }