/// <summary>
        /// Create <SignedSignatureProperties>
        /// </summary>
        /// <param name="document"></param>
        /// <returns></returns>
        internal XmlElement CreateXadesSignatureProperties(XmlDocument document, X509Certificate2 certificate, SignatureType xadesVersion)
        {
            XmlElement signatureProperties = document.CreateElement("SignedSignatureProperties", Xades.XadesNamespaceUrl);

            // signing time; required for 1.1.1
            if (SigningTime.HasValue || xadesVersion < SignatureType.Xades132)
            {
                signatureProperties.CreateChild("SigningTime", Xades.XadesNamespaceUrl, (SigningTime ?? DateTime.Now).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"));
            }
            // signing certificate; can be omitted >= 1.3.2
            if (IncludeSigningCertificate || xadesVersion < SignatureType.Xades132)
            {
                XmlElement signingCertificate = signatureProperties.CreateChild("SigningCertificate", Xades.XadesNamespaceUrl);
                XmlElement signingCert        = signingCertificate.CreateChild("Cert", Xades.XadesNamespaceUrl);
                // certificate digest
                HashAlgorithm hashAlg = CryptoConfig.CreateFromName(CertificateDigest) as HashAlgorithm;
                if (hashAlg == null)
                {
                    throw new CryptographicException("Invalid digest method");
                }
                DigestAlgAndValue certDigest = new DigestAlgAndValue()
                {
                    Algorithm = CertificateDigest, Digest = hashAlg.ComputeHash(certificate.RawData)
                };
                signingCert.AppendChild(certDigest.CreateXml(signingCert, "CertDigest", Xades.XadesNamespaceUrl));
                // certificate issuer
                XmlElement issuerSerial = signingCert.CreateChild("IssuerSerial", Xades.XadesNamespaceUrl);
                issuerSerial.CreateChild("X509IssuerName", SignedXml.XmlDsigNamespaceUrl, certificate.Issuer);
                issuerSerial.CreateChild("X509SerialNumber", SignedXml.XmlDsigNamespaceUrl, XadesUtils.ToDecimal(XadesUtils.HexToBytes(certificate.SerialNumber)));
            }
            // signature policy; can be omitted >= 1.3.2
            XmlElement sigPolicyId = PolicyId?.GetObjectIdentifier(document, "SigPolicyId", Xades.XadesNamespaceUrl);

            if (PolicyImplied || xadesVersion < SignatureType.Xades132 || sigPolicyId != null)
            {
                XmlElement signaturePolicyIdentifier = signatureProperties.CreateChild("SignaturePolicyIdentifier", Xades.XadesNamespaceUrl);
                // policy implied if specified (or policyid not specified)
                if (PolicyImplied || sigPolicyId == null)
                {
                    signaturePolicyIdentifier.CreateChild("SignaturePolicyImplied", Xades.XadesNamespaceUrl);
                }
                else if (sigPolicyId != null)
                {
                    XmlElement signaturePolicyId = signaturePolicyIdentifier.CreateChild("SignaturePolicyId", Xades.XadesNamespaceUrl);
                    signaturePolicyId.AppendChild(sigPolicyId);

                    if (PolicyTransformChain != null && PolicyTransformChain.Count > 0)
                    {
                        MethodInfo getXmlInfo = typeof(TransformChain).GetMethod("GetXml", BindingFlags.NonPublic | BindingFlags.Instance);
                        signaturePolicyId.AppendChild((XmlElement)getXmlInfo.Invoke(PolicyTransformChain, new object[] { document, SignedXml.XmlDsigNamespaceUrl }));
                    }

                    if (PolicyDigest == null)
                    {
                        CalculatePolicyHash(PolicyURIs.FirstOrDefault() ?? PolicyId.Identifier);
                    }

                    DigestAlgAndValue policyHash = new DigestAlgAndValue()
                    {
                        Algorithm = PolicyDigestMethod, Digest = PolicyDigest
                    };
                    policyHash.CreateXml(signaturePolicyId, "SigPolicyHash", Xades.XadesNamespaceUrl);

                    XmlElement sigPolicyQualifiers = document.CreateElement("SigPolicyQualifiers", Xades.XadesNamespaceUrl);
                    if (PolicyURIs != null && PolicyURIs.Count > 0)
                    {
                        foreach (string uri in PolicyURIs)
                        {
                            sigPolicyQualifiers.CreateChild("SigPolicyQualifier", Xades.XadesNamespaceUrl).CreateChild("SPURI", Xades.XadesNamespaceUrl, uri);
                        }
                    }
                    if (PolicyNotices != null && PolicyNotices.Count > 0)
                    {
                        foreach (PolicyUserNotice notice in PolicyNotices)
                        {
                            notice.CreateXml(sigPolicyQualifiers.CreateChild("SigPolicyQualifier", Xades.XadesNamespaceUrl));
                        }
                    }
                    if (sigPolicyQualifiers.ChildNodes.Count > 0)
                    {
                        signaturePolicyId.AppendChild(sigPolicyQualifiers);
                    }
                }
            }
            return(signatureProperties);
        }