/// <summary>
        /// Reads the attribute assignment expression.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns></returns>
        protected virtual XacmlAttributeAssignmentExpression ReadAttributeAssignmentExpression(XmlReader reader) {
            Contract.Requires<ArgumentNullException>(reader != null, "reader");
            Contract.Requires<XmlException>(reader.IsStartElement(XacmlConstants.ElementNames.AttributeAssignmentExpression, this.version.NamespacePolicy));

            Uri attributeId = this.ReadAttribute<Uri>(reader, XacmlConstants.AttributeNames.AttributeId);
            Uri category = this.ReadAttribute<Uri>(reader, XacmlConstants.AttributeNames.Category, isRequered: false);
            string issuer = this.ReadAttribute<string>(reader, XacmlConstants.AttributeNames.Issuer, isRequered: false);

            reader.ReadStartElement(XacmlConstants.ElementNames.AttributeAssignmentExpression, this.version.NamespacePolicy);

            XacmlAttributeAssignmentExpression result = new XacmlAttributeAssignmentExpression(
                attributeId,
                this.ReadExpressionType(reader)
                );

            reader.ReadEndElement();

            return result;
        }
        protected virtual XacmlAttributeAssignment AttributeAssignmentCreate(object value, XacmlAttributeAssignmentExpression expression) {
            Contract.Requires<ArgumentNullException>(value != null);
            Contract.Requires<ArgumentNullException>(expression != null);

            TypeConverter con = TypeDescriptor.GetConverter(value.GetType());
            string type = this.types[con];

            Uri typeUri;
            Uri.TryCreate(this.types[con], UriKind.RelativeOrAbsolute, out typeUri);

            XacmlAttributeAssignment result = new XacmlAttributeAssignment(expression.AttributeId, typeUri, value.ToString()) {
                Category = expression.Category,
                Issuer = expression.Issuer
            };

            return result;
        }
        /// <summary>
        /// Writes the attribute assignment expression.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="data">The data.</param>
        protected virtual void WriteAttributeAssignmentExpression(XmlWriter writer, XacmlAttributeAssignmentExpression data) {
            Contract.Requires<ArgumentNullException>(writer != null);
            Contract.Requires<ArgumentNullException>(data != null);

            writer.WriteStartElement(XacmlConstants.Prefixes.Policy, XacmlConstants.ElementNames.AttributeAssignmentExpression, this.version.NamespacePolicy);

            writer.WriteAttributeString(XacmlConstants.AttributeNames.AttributeId, data.AttributeId.OriginalString);

            if (data.Category != null) {
                writer.WriteAttributeString(XacmlConstants.AttributeNames.Category, data.Category.OriginalString);
            }

            if (!string.IsNullOrEmpty(data.Issuer)) {
                writer.WriteAttributeString(XacmlConstants.AttributeNames.Issuer, data.Issuer);
            }

            this.WriteExpressionType(writer, data);

            writer.WriteEndElement();
        }
        /// <summary>
        /// XacmlAttributeAssignmentExpression ----> XacmlAttributeAssignment
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        protected virtual IEnumerable<XacmlAttributeAssignment> AttributeAssignmentExpressionEvaluate(XacmlAttributeAssignmentExpression expression) {
            Contract.Requires<ArgumentNullException>(expression != null);

            object expressionResult = this.ExpressionEvaluate(expression.Property);

            if (expressionResult == null) {
                return null;
            }

            List<XacmlAttributeAssignment> result = new List<XacmlAttributeAssignment>();

            if ((typeof(System.Collections.IEnumerable)).IsAssignableFrom(expressionResult.GetType()) && expressionResult.GetType() != typeof(string)) {
                foreach (object elem in (IEnumerable)expressionResult) {
                    result.Add(this.AttributeAssignmentCreate(elem, expression));
                }
            }
            else {
                result.Add(this.AttributeAssignmentCreate(expressionResult, expression));
            }

            return result;
        }