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

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

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

            reader.ReadStartElement(XacmlConstants.ElementNames.ObligationExpression, 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 obligation expression.
        /// </summary>
        /// <param name="writer">The writer.</param>
        /// <param name="data">The data.</param>
        protected virtual void WriteObligationExpression(XmlWriter writer, XacmlObligationExpression data) {
            Contract.Requires<ArgumentNullException>(writer != null);
            Contract.Requires<ArgumentNullException>(data != null);

            writer.WriteStartElement(XacmlConstants.Prefixes.Policy, XacmlConstants.ElementNames.ObligationExpression, this.version.NamespacePolicy);
            writer.WriteAttributeString(XacmlConstants.AttributeNames.ObligationId, data.ObligationId.OriginalString);
            writer.WriteAttributeString(XacmlConstants.AttributeNames.FulfillOn, data.FulfillOn.ToString());

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

            writer.WriteEndElement();
        }