/// <summary>
        /// Writes the &lt;saml:Evidence> element.
        /// </summary>
        /// <param name="writer">A <see cref="XmlWriter"/> to serialize the <see cref="Saml2Evidence"/>.</param>
        /// <param name="data">The <see cref="Saml2Evidence"/> to serialize.</param>
        protected virtual void WriteEvidence(XmlWriter writer, Saml2Evidence data)
        {
            if (null == writer)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("writer");
            }

            if (null == data)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("data");
            }

            if ((data.AssertionIdReferences == null || 0 == data.AssertionIdReferences.Count)
               && (data.Assertions == null || 0 == data.Assertions.Count)
               && (data.AssertionUriReferences == null || 0 == data.AssertionUriReferences.Count))
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                    new InvalidOperationException(SR.GetString(SR.ID4120)));
            }

            // <Evidence>
            writer.WriteStartElement(Saml2Constants.Elements.Evidence, Saml2Constants.Namespace);

            // <AssertionIDRef> 0-OO
            foreach (Saml2Id id in data.AssertionIdReferences)
            {
                writer.WriteElementString(Saml2Constants.Elements.AssertionIDRef, Saml2Constants.Namespace, id.Value);
            }

            // <AssertionURIRef> 0-OO
            foreach (Uri uri in data.AssertionUriReferences)
            {
                writer.WriteElementString(Saml2Constants.Elements.AssertionURIRef, Saml2Constants.Namespace, uri.AbsoluteUri);
            }

            // <Assertion> 0-OO
            foreach (Saml2Assertion assertion in data.Assertions)
            {
                this.WriteAssertion(writer, assertion);
            }

            // </Evidence>
            writer.WriteEndElement();
        }
        /// <summary>
        /// Reads the &lt;saml:Evidence> element.
        /// </summary>
        /// <param name="reader">A <see cref="XmlReader"/> positioned at a <see cref="Saml2Evidence"/> element.</param>
        /// <returns>A <see cref="Saml2Evidence"/> instance.</returns>
        protected virtual Saml2Evidence ReadEvidence(XmlReader reader)
        {
            if (null == reader)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("reader");
            }

            // throw if wrong element
            if (!reader.IsStartElement(Saml2Constants.Elements.Evidence, Saml2Constants.Namespace))
            {
                reader.ReadStartElement(Saml2Constants.Elements.Evidence, Saml2Constants.Namespace);
            }

            // disallow empty
            if (reader.IsEmptyElement)
            {
                throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID3061, Saml2Constants.Elements.Evidence, Saml2Constants.Namespace));
            }

            try
            {
                Saml2Evidence evidence = new Saml2Evidence();

                // @attributes

                // @xsi:type
                XmlUtil.ValidateXsiType(reader, Saml2Constants.Types.EvidenceType, Saml2Constants.Namespace);

                reader.Read();

                // <AssertionIDRef|AssertionURIRef|Assertion|EncryptedAssertion> 0-OO
                while (reader.IsStartElement())
                {
                    if (reader.IsStartElement(Saml2Constants.Elements.AssertionIDRef, Saml2Constants.Namespace))
                    {
                        evidence.AssertionIdReferences.Add(ReadSimpleNCNameElement(reader));
                    }
                    else if (reader.IsStartElement(Saml2Constants.Elements.AssertionURIRef, Saml2Constants.Namespace))
                    {
                        evidence.AssertionUriReferences.Add(ReadSimpleUriElement(reader));
                    }
                    else if (reader.IsStartElement(Saml2Constants.Elements.Assertion, Saml2Constants.Namespace))
                    {
                        evidence.Assertions.Add(this.ReadAssertion(reader));
                    }
                    else if (reader.IsStartElement(Saml2Constants.Elements.EncryptedAssertion, Saml2Constants.Namespace))
                    {
                        evidence.Assertions.Add(this.ReadAssertion(reader));
                    }
                }

                if (0 == evidence.AssertionIdReferences.Count
                        && 0 == evidence.Assertions.Count
                        && 0 == evidence.AssertionUriReferences.Count)
                {
                    throw DiagnosticUtility.ThrowHelperXml(reader, SR.GetString(SR.ID4120));
                }

                reader.ReadEndElement();

                return evidence;
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                Exception wrapped = TryWrapReadException(reader, e);
                if (null == wrapped)
                {
                    throw;
                }
                else
                {
                    throw wrapped;
                }
            }
        }