/// <summary>
        /// This gets called on the STS to serialize the token
        /// The token looks like this
        ///     <MyDecisionToken Id="someId here">
        ///         <Decision>True</Decision>
        ///         <Key>key bytes</Key>
        ///         <Signature>...</Signature>
        ///     </MyDecisionToken>
        /// </summary>
        /// <param name="writer">The xml writer.</param>
        /// <param name="token">The security token that will be written.</param>
        /// <exception cref="ArgumentException">When the token is null.</exception>
        public override void WriteToken(XmlWriter writer, SecurityToken token)
        {
            Console.WriteLine("CustomTokenHandler.WriteToken called");
            MyDecisionToken decisionToken = token as MyDecisionToken;

            if (decisionToken == null)
            {
                throw new ArgumentException("The given token must be a MyDecisionToken", "token");
            }

            EnvelopedSignatureWriter envWriter = new EnvelopedSignatureWriter(writer, decisionToken.SigningCredentials, decisionToken.Id, WSSecurityTokenSerializer.DefaultInstance);

            // Start the tokenName
            envWriter.WriteStartElement(TokenName, TokenNamespace);
            envWriter.WriteAttributeString(Id, token.Id);

            // Write the decision element
            Console.WriteLine("- decision being written: {0}", decisionToken.Decision);
            envWriter.WriteElementString(Decision, TokenNamespace, Convert.ToString(decisionToken.Decision));

            // Write the key
            envWriter.WriteElementString(Key, TokenNamespace, Convert.ToBase64String(((MyDecisionToken)token).RetrieveKeyBytes()));

            // Close the TokenName element
            envWriter.WriteEndElement();
        }
        /// <summary>
        /// Creates a MyDecision type security token based on the description in the security token descriptor.
        /// </summary>
        /// <param name="tokenDescriptor">The token descriptor.</param>
        /// <returns>The security token.</returns>
        public override SecurityToken CreateToken(SecurityTokenDescriptor tokenDescriptor)
        {
            Console.WriteLine("CustomTokenHandler.CreateToken called");
            SymmetricProofDescriptor symmetric = tokenDescriptor.Proof as SymmetricProofDescriptor;

            if (symmetric == null)
            {
                throw new InvalidOperationException("The MyDecisionToken must be symmetric key based.");
            }

            bool decision = false;

            //
            // Retrieve the decision from the issued claims
            //
            foreach (Claim claim in tokenDescriptor.Subject.Claims)
            {
                if (StringComparer.Ordinal.Equals(claim.ClaimType, DecisionClaimType) &&
                    StringComparer.Ordinal.Equals(claim.ValueType, ClaimValueTypes.Boolean))
                {
                    Console.WriteLine("- decision claim found: {0}", claim.Value);
                    decision = Convert.ToBoolean(claim.Value);
                }
            }

            //
            // This is just an example to show how to issue a custom token. The key is created by the STS
            // through the proof token.
            //
            SecurityToken token = new MyDecisionToken(decision, tokenDescriptor.SigningCredentials, symmetric.GetKeyBytes());

            //
            // Encrypt the token
            //
            EncryptingCredentials encryptingCredentials = GetEncryptingCredentials(tokenDescriptor);

            if (encryptingCredentials != null)
            {
                token = new EncryptedSecurityToken(token, encryptingCredentials);
            }

            return(token);
        }