/// <summary>
        /// Calculates the signature for a given message.
        /// </summary>
        /// <param name="signedMessage">The message to sign or verify.</param>
        /// <param name="association">The association to use to sign the message.</param>
        /// <returns>The calculated signature of the method.</returns>
        protected string GetSignature(ITamperResistantOpenIdMessage signedMessage, Association association)
        {
            Requires.NotNull(signedMessage, "signedMessage");
            Requires.That(!string.IsNullOrEmpty(signedMessage.SignedParameterOrder), "signedMessage", "SignedParameterOrder must not be null or empty.");
            Requires.NotNull(association, "association");

            // Prepare the parts to sign, taking care to replace an openid.mode value
            // of check_authentication with its original id_res so the signature matches.
            MessageDictionary dictionary = this.Channel.MessageDescriptions.GetAccessor(signedMessage);
            var parametersToSign         = from name in signedMessage.SignedParameterOrder.Split(',')
                                           let prefixedName = Protocol.V20.openid.Prefix + name
                                                              select new KeyValuePair <string, string>(name, dictionary.GetValueOrThrow(prefixedName, signedMessage));

            byte[] dataToSign = KeyValueFormEncoding.GetBytes(parametersToSign);
            string signature  = Convert.ToBase64String(association.Sign(dataToSign));

            if (Logger.Signatures.IsDebugEnabled)
            {
                Logger.Signatures.DebugFormat(
                    "Signing these message parts: {0}{1}{0}Base64 representation of signed data: {2}{0}Signature: {3}",
                    Environment.NewLine,
                    parametersToSign.ToStringDeferred(),
                    Convert.ToBase64String(dataToSign),
                    signature);
            }

            return(signature);
        }