/// <summary>
 /// When finished with a <see cref="SignatureProvider"/> call this method for cleanup. The default behavior is to call <see cref="SignatureProvider.Dispose()"/>
 /// </summary>
 /// <param name="signatureProvider"><see cref="SignatureProvider"/> to be released.</param>
 public virtual void ReleaseSignatureProvider(SignatureProvider signatureProvider)
 {
     if (signatureProvider != null)
     {
         signatureProvider.Dispose();
     }
 }
        private SignatureProvider CreateSignatureProvider(SecurityKey key, string algorithm, bool willCreateSignatures)
        {
            if (key == null)
            {
                throw LogHelper.LogArgumentNullException(nameof(key));
            }

            if (string.IsNullOrEmpty(algorithm))
            {
                throw LogHelper.LogArgumentNullException(nameof(algorithm));
            }

            if (CustomCryptoProvider != null && CustomCryptoProvider.IsSupportedAlgorithm(algorithm, key, willCreateSignatures))
            {
                SignatureProvider signatureProvider = CustomCryptoProvider.Create(algorithm, key, willCreateSignatures) as SignatureProvider;
                if (signatureProvider == null)
                {
                    throw LogHelper.LogExceptionMessage(new InvalidOperationException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10646, algorithm, key, typeof(SignatureProvider))));
                }

                return(signatureProvider);
            }

            if (!IsSupportedAlgorithm(algorithm, key))
            {
                throw LogHelper.LogExceptionMessage(new ArgumentException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10634, algorithm, key)));
            }

            AsymmetricSecurityKey asymmetricKey = key as AsymmetricSecurityKey;

            if (asymmetricKey != null)
            {
                return(new AsymmetricSignatureProvider(asymmetricKey, algorithm, willCreateSignatures));
            }

            SymmetricSecurityKey symmetricKey = key as SymmetricSecurityKey;

            if (symmetricKey != null)
            {
                return(new SymmetricSignatureProvider(symmetricKey, algorithm));
            }

            JsonWebKey jsonWebKey = key as JsonWebKey;

            if (jsonWebKey != null)
            {
                if (jsonWebKey.Kty != null)
                {
                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.RSA || jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.EllipticCurve)
                    {
                        return(new AsymmetricSignatureProvider(key, algorithm, willCreateSignatures));
                    }

                    if (jsonWebKey.Kty == JsonWebAlgorithmsKeyTypes.Octet)
                    {
                        return(new SymmetricSignatureProvider(key, algorithm));
                    }
                }
            }

            // TODO improve this message. Nothing about JsonWebKey is mentioned.
            throw LogHelper.LogExceptionMessage(new ArgumentException(String.Format(CultureInfo.InvariantCulture, LogMessages.IDX10600, typeof(SignatureProvider), typeof(SecurityKey), typeof(AsymmetricSecurityKey), typeof(SymmetricSecurityKey), key.GetType())));
        }