DerivedKeySecurityToken ReadDerivedKeyTokenCore (
			XmlReader reader, SecurityTokenResolver tokenResolver)
		{
			if (tokenResolver == null)
				throw new ArgumentNullException ("tokenResolver");
			string id = reader.GetAttribute ("Id", Constants.WsuNamespace);
			string algorithm = reader.MoveToAttribute ("Algorithm") ? reader.Value : null;
			reader.MoveToElement ();
			reader.ReadStartElement ();
			reader.MoveToContent ();
			SecurityKeyIdentifierClause kic = ReadKeyIdentifierClause (reader);
			int? generation = null, offset = null, length = null;
			byte [] nonce = null;
			string name = null, label = null;
			for (reader.MoveToContent ();
			       reader.NodeType != XmlNodeType.EndElement;
			       reader.MoveToContent ())
				switch (reader.LocalName) {
				case "Properties":
					reader.ReadStartElement ("Properties", Constants.WsscNamespace);
					for (reader.MoveToContent ();
					       reader.NodeType != XmlNodeType.EndElement;
					       reader.MoveToContent ())
						switch (reader.LocalName) {
						case "Name":
							name = reader.ReadElementContentAsString ("Name", Constants.WsscNamespace);
							break;
						case "Label":
							label = reader.ReadElementContentAsString ("Label", Constants.WsscNamespace);
							break;
						case "Nonce":
							nonce = Convert.FromBase64String (reader.ReadElementContentAsString ("Nonce", Constants.WsscNamespace));
							break;
						}
					reader.ReadEndElement ();
					break;
				case "Offset":
					offset = reader.ReadElementContentAsInt ("Offset", Constants.WsscNamespace);
					break;
				case "Length":
					length = reader.ReadElementContentAsInt ("Length", Constants.WsscNamespace);
					break;
				case "Nonce":
					nonce = Convert.FromBase64String (reader.ReadElementContentAsString ("Nonce", Constants.WsscNamespace));
					break;
				case "Label":
					label = reader.ReadElementContentAsString ("Label", Constants.WsscNamespace);
					break;
				}
			reader.ReadEndElement ();

			// resolve key reference
			SymmetricSecurityKey key = tokenResolver.ResolveSecurityKey (kic) as SymmetricSecurityKey;
			if (key == null)
				throw new XmlException ("Cannot resolve the security key referenced by the DerivedKeyToken as a symmetric key");

			return new DerivedKeySecurityToken (id, algorithm, kic, key, name, generation, offset, length, label, nonce);
		}
        protected static string SerializeToken(SimpleWebToken swt, SecurityTokenResolver tokenResolver)
        {
            StringBuilder builder = new StringBuilder(64);
            builder.Append("Id=");
            builder.Append(swt.Id);
            builder.Append('&');

            builder.Append(IssuerLabel);
            builder.Append('=');
            builder.Append(swt.Issuer);

            if (swt.Parameters.Count > 0)
            {
                builder.Append('&');
                foreach (string key in swt.Parameters.AllKeys)
                {
                    builder.Append(key);
                    builder.Append('=');
                    builder.Append(swt.Parameters[key]);
                    builder.Append('&');
                }
            }
            else
            {
                builder.Append('&');
            }

            builder.Append(ExpiresOnLabel);
            builder.Append('=');
            builder.Append(GetExpiresOn(swt.TokenValidity));

            if (!string.IsNullOrEmpty(swt.Audience))
            {
                builder.Append('&');
                builder.Append(AudienceLabel);
                builder.Append('=');
                builder.Append(swt.Audience);
            }

            builder.Append('&');
            builder.Append(SignatureAlgorithmLabel);
            builder.Append('=');
            builder.Append(SignatureAlgorithm);

            var keyIdentifierClause = new DictionaryBasedKeyIdentifierClause(ToDictionary(swt));
            InMemorySymmetricSecurityKey securityKey;
            try
            {
                securityKey = (InMemorySymmetricSecurityKey)tokenResolver.ResolveSecurityKey(keyIdentifierClause);
            }
            catch (InvalidOperationException)
            {
                throw new SecurityTokenValidationException(string.Format(CultureInfo.InvariantCulture, "Simmetryc key was not found for the key identifier clause: Keys='{0}', Values='{1}'", string.Join(",", keyIdentifierClause.Dictionary.Keys.ToArray()), string.Join(",", keyIdentifierClause.Dictionary.Values.ToArray())));
            }

            string signature = GenerateSignature(builder.ToString(), securityKey.GetSymmetricKey());
            builder.Append("&" + SignatureLabel + "=");
            builder.Append(signature);

            return builder.ToString();
        }