/// <summary>
        /// Reads the advice expression.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <returns></returns>
        /// <exception cref="XacmlSerializationException">Wrong XacmlEffectType value</exception>
        protected virtual XacmlAdviceExpression ReadAdviceExpression(XmlReader reader) {
            Contract.Requires<ArgumentNullException>(reader != null, "reader");
            Contract.Requires<XmlException>(reader.IsStartElement(XacmlConstants.ElementNames.AdviceExpression, this.version.NamespacePolicy));

            string appliesTo = this.ReadAttribute<string>(reader, XacmlConstants.AttributeNames.AppliesTo);
            XacmlEffectType effectType = XacmlEffectType.Deny;
            if (string.Equals(appliesTo, "Deny", StringComparison.OrdinalIgnoreCase)) {
                effectType = XacmlEffectType.Deny;
            }
            else if (string.Equals(appliesTo, "Permit", StringComparison.OrdinalIgnoreCase)) {
                effectType = XacmlEffectType.Permit;
            }
            else {
                throw Diagnostic.DiagnosticTools.ExceptionUtil.ThrowHelperError(new XacmlSerializationException("Wrong XacmlEffectType value"));
            }

            XacmlAdviceExpression result = new XacmlAdviceExpression(
                this.ReadAttribute<Uri>(reader, XacmlConstants.AttributeNames.AdviceId),
                effectType
                );

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

            this.ReadList<XacmlAttributeAssignmentExpression>(result.AttributeAssignmentExpressions, XacmlConstants.ElementNames.AttributeAssignmentExpression, this.version.NamespacePolicy, this.ReadAttributeAssignmentExpression, reader, isRequired: false);

            reader.ReadEndElement();

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

            writer.WriteStartElement(XacmlConstants.Prefixes.Policy, XacmlConstants.ElementNames.AdviceExpression, this.version.NamespacePolicy);
            writer.WriteAttributeString(XacmlConstants.AttributeNames.AdviceId, data.AdviceId.OriginalString);
            writer.WriteAttributeString(XacmlConstants.AttributeNames.AppliesTo, data.AppliesTo.ToString());

            foreach (XacmlAttributeAssignmentExpression expr in data.AttributeAssignmentExpressions) {
                this.WriteAttributeAssignmentExpression(writer, expr);
            }

            writer.WriteEndElement();
        }