func (a *AuthnStatement) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias AuthnStatement
	aux := &struct {
		AuthnInstant        RelaxedTime  `xml:",attr"`
		SessionNotOnOrAfter *RelaxedTime `xml:",attr,omitempty"`
		*Alias
	}{
		AuthnInstant:        RelaxedTime(a.AuthnInstant),
		SessionNotOnOrAfter: (*RelaxedTime)(a.SessionNotOnOrAfter),
		Alias:               (*Alias)(a),
	}
	return e.EncodeElement(aux, start)
}
MarshalXML implements xml.Marshaler
package saml
import (
	"bytes"
	"compress/flate"
	"encoding/xml"
	"strconv"
	"time"
	"github.com/beevik/etree"
	"github.com/russellhaering/goxmldsig/etreeutils"
)
type AuthnRequest struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol AuthnRequest"`
	ID           string    `xml:",attr"`
	Version      string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Destination  string    `xml:",attr"`
	Consent      string    `xml:",attr"`
	Issuer       *Issuer   `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	Signature    *etree.Element
	Subject      *Subject
	NameIDPolicy *NameIDPolicy `xml:"urn:oasis:names:tc:SAML:2.0:protocol NameIDPolicy"`
	Conditions   *Conditions
	ForceAuthn                     *bool  `xml:",attr"`
	IsPassive                      *bool  `xml:",attr"`
	AssertionConsumerServiceIndex  string `xml:",attr"`
	AssertionConsumerServiceURL    string `xml:",attr"`
	ProtocolBinding                string `xml:",attr"`
	AttributeConsumingServiceIndex string `xml:",attr"`
	ProviderName                   string `xml:",attr"`
}
type LogoutRequest struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol LogoutRequest"`
	ID           string    `xml:",attr"`
	Version      string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Destination  string    `xml:",attr"`
	Issuer       *Issuer   `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	NameID       *NameID
	Signature    *etree.Element
	SessionIndex *SessionIndex `xml:"SessionIndex"`
}
func (r *LogoutRequest) Element() *etree.Element {
	el := etree.NewElement("samlp:LogoutRequest")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:2.0:protocol")
	el.CreateAttr("ID", r.ID)
	el.CreateAttr("Version", r.Version)
	el.CreateAttr("IssueInstant", r.IssueInstant.Format(timeFormat))
	if r.Destination != "" {
		el.CreateAttr("Destination", r.Destination)
	}
	if r.Issuer != nil {
		el.AddChild(r.Issuer.Element())
	}
	if r.NameID != nil {
		el.AddChild(r.NameID.Element())
	}
	if r.Signature != nil {
		el.AddChild(r.Signature)
	}
	if r.SessionIndex != nil {
		el.AddChild(r.SessionIndex.Element())
	}
	return el
}
func (r *LogoutRequest) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias LogoutRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		IssueInstant: RelaxedTime(r.IssueInstant),
		Alias:        (*Alias)(r),
	}
	return e.Encode(aux)
}
func (r *LogoutRequest) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias LogoutRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(r),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	r.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
func (r *LogoutRequest) Bytes() ([]byte, error) {
	doc := etree.NewDocument()
	doc.SetRoot(r.Element())
	buf, err := doc.WriteToBytes()
	if err != nil {
		return nil, err
	}
	return buf, nil
}
func (r *LogoutRequest) Deflate() ([]byte, error) {
	buf, err := r.Bytes()
	if err != nil {
		return nil, err
	}
	var b bytes.Buffer
	writer, err := flate.NewWriter(&b, flate.DefaultCompression)
	if err != nil {
		return nil, err
	}
	if _, err := writer.Write(buf); err != nil {
		return nil, err
	}
	if err := writer.Close(); err != nil {
		return nil, err
	}
	return b.Bytes(), nil
}
func (r *AuthnRequest) Element() *etree.Element {
	el := etree.NewElement("samlp:AuthnRequest")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:2.0:protocol")
	el.CreateAttr("ID", r.ID)
	el.CreateAttr("Version", r.Version)
	el.CreateAttr("IssueInstant", r.IssueInstant.Format(timeFormat))
	if r.Destination != "" {
		el.CreateAttr("Destination", r.Destination)
	}
	if r.Consent != "" {
		el.CreateAttr("Consent", r.Consent)
	}
	if r.Issuer != nil {
		el.AddChild(r.Issuer.Element())
	}
	if r.Signature != nil {
		el.AddChild(r.Signature)
	}
	if r.Subject != nil {
		el.AddChild(r.Subject.Element())
	}
	if r.NameIDPolicy != nil {
		el.AddChild(r.NameIDPolicy.Element())
	}
	if r.Conditions != nil {
		el.AddChild(r.Conditions.Element())
	}
	if r.ForceAuthn != nil {
		el.CreateAttr("ForceAuthn", strconv.FormatBool(*r.ForceAuthn))
	}
	if r.IsPassive != nil {
		el.CreateAttr("IsPassive", strconv.FormatBool(*r.IsPassive))
	}
	if r.AssertionConsumerServiceIndex != "" {
		el.CreateAttr("AssertionConsumerServiceIndex", r.AssertionConsumerServiceIndex)
	}
	if r.AssertionConsumerServiceURL != "" {
		el.CreateAttr("AssertionConsumerServiceURL", r.AssertionConsumerServiceURL)
	}
	if r.ProtocolBinding != "" {
		el.CreateAttr("ProtocolBinding", r.ProtocolBinding)
	}
	if r.AttributeConsumingServiceIndex != "" {
		el.CreateAttr("AttributeConsumingServiceIndex", r.AttributeConsumingServiceIndex)
	}
	if r.ProviderName != "" {
		el.CreateAttr("ProviderName", r.ProviderName)
	}
	return el
}
func (r *AuthnRequest) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias AuthnRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		IssueInstant: RelaxedTime(r.IssueInstant),
		Alias:        (*Alias)(r),
	}
	return e.Encode(aux)
}
func (r *AuthnRequest) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias AuthnRequest
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(r),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	r.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
type Issuer struct {
	XMLName         xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	NameQualifier   string   `xml:",attr"`
	SPNameQualifier string   `xml:",attr"`
	Format          string   `xml:",attr"`
	SPProvidedID    string   `xml:",attr"`
	Value           string   `xml:",chardata"`
}
func (a *Issuer) Element() *etree.Element {
	el := etree.NewElement("saml:Issuer")
	if a.NameQualifier != "" {
		el.CreateAttr("NameQualifier", a.NameQualifier)
	}
	if a.SPNameQualifier != "" {
		el.CreateAttr("SPNameQualifier", a.SPNameQualifier)
	}
	if a.Format != "" {
		el.CreateAttr("Format", a.Format)
	}
	if a.SPProvidedID != "" {
		el.CreateAttr("SPProvidedID", a.SPProvidedID)
	}
	el.SetText(a.Value)
	return el
}
type NameIDPolicy struct {
	XMLName         xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol NameIDPolicy"`
	Format          *string  `xml:",attr"`
	SPNameQualifier *string  `xml:",attr"`
	AllowCreate     *bool    `xml:",attr"`
}
func (a *NameIDPolicy) Element() *etree.Element {
	el := etree.NewElement("samlp:NameIDPolicy")
	if a.Format != nil && *a.Format != "" {
		el.CreateAttr("Format", *a.Format)
	}
	if a.SPNameQualifier != nil {
		el.CreateAttr("SPNameQualifier", *a.SPNameQualifier)
	}
	if a.AllowCreate != nil {
		el.CreateAttr("AllowCreate", strconv.FormatBool(*a.AllowCreate))
	}
	return el
}
type Response struct {
	XMLName      xml.Name  `xml:"urn:oasis:names:tc:SAML:2.0:protocol Response"`
	ID           string    `xml:",attr"`
	InResponseTo string    `xml:",attr"`
	Version      string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Destination  string    `xml:",attr"`
	Consent      string    `xml:",attr"`
	Issuer       *Issuer   `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	Signature    *etree.Element
	Status       Status `xml:"urn:oasis:names:tc:SAML:2.0:protocol Status"`
	EncryptedAssertion *etree.Element `xml:"urn:oasis:names:tc:SAML:2.0:assertion EncryptedAssertion"`
	Assertion *Assertion `xml:"urn:oasis:names:tc:SAML:2.0:assertion Assertion"`
}
func (r *Response) Element() *etree.Element {
	el := etree.NewElement("samlp:Response")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:2.0:protocol")
	el.CreateAttr("xmlns:xs", "http://www.w3.org/2001/XMLSchema")
	el.CreateAttr("ID", r.ID)
	if r.InResponseTo != "" {
		el.CreateAttr("InResponseTo", r.InResponseTo)
	}
	el.CreateAttr("Version", r.Version)
	el.CreateAttr("IssueInstant", r.IssueInstant.Format(timeFormat))
	if r.Destination != "" {
		el.CreateAttr("Destination", r.Destination)
	}
	if r.Consent != "" {
		el.CreateAttr("Consent", r.Consent)
	}
	if r.Issuer != nil {
		el.AddChild(r.Issuer.Element())
	}
	if r.Signature != nil {
		el.AddChild(r.Signature)
	}
	el.AddChild(r.Status.Element())
	if r.EncryptedAssertion != nil {
		el.AddChild(r.EncryptedAssertion)
	}
	if r.Assertion != nil {
		el.AddChild(r.Assertion.Element())
	}
	return el
}
func (r *Response) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias Response
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		IssueInstant: RelaxedTime(r.IssueInstant),
		Alias:        (*Alias)(r),
	}
	return e.Encode(aux)
}
func (r *Response) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias Response
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(r),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	r.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
type Status struct {
	XMLName       xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol Status"`
	StatusCode    StatusCode
	StatusMessage *StatusMessage
	StatusDetail  *StatusDetail
}
func (s *Status) Element() *etree.Element {
	el := etree.NewElement("samlp:Status")
	el.AddChild(s.StatusCode.Element())
	if s.StatusMessage != nil {
		el.AddChild(s.StatusMessage.Element())
	}
	if s.StatusDetail != nil {
		el.AddChild(s.StatusDetail.Element())
	}
	return el
}
type StatusCode struct {
	XMLName    xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:protocol StatusCode"`
	Value      string   `xml:",attr"`
	StatusCode *StatusCode
}
func (s *StatusCode) Element() *etree.Element {
	el := etree.NewElement("samlp:StatusCode")
	el.CreateAttr("Value", s.Value)
	if s.StatusCode != nil {
		el.AddChild(s.StatusCode.Element())
	}
	return el
}
var StatusSuccess = "urn:oasis:names:tc:SAML:2.0:status:Success"
const (
	StatusRequester = "urn:oasis:names:tc:SAML:2.0:status:Requester"
	StatusResponder = "urn:oasis:names:tc:SAML:2.0:status:Responder"
	StatusVersionMismatch = "urn:oasis:names:tc:SAML:2.0:status:VersionMismatch"
	StatusAuthnFailed = "urn:oasis:names:tc:SAML:2.0:status:AuthnFailed"
	StatusInvalidAttrNameOrValue = "urn:oasis:names:tc:SAML:2.0:status:InvalidAttrNameOrValue"
	StatusInvalidNameIDPolicy = "urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy"
	StatusNoAuthnContext = "urn:oasis:names:tc:SAML:2.0:status:NoAuthnContext"
	StatusNoAvailableIDP = "urn:oasis:names:tc:SAML:2.0:status:NoAvailableIDP"
	StatusNoPassive = "urn:oasis:names:tc:SAML:2.0:status:NoPassive"  
	StatusNoSupportedIDP = "urn:oasis:names:tc:SAML:2.0:status:NoSupportedIDP"
	StatusPartialLogout = "urn:oasis:names:tc:SAML:2.0:status:PartialLogout"
	StatusProxyCountExceeded = "urn:oasis:names:tc:SAML:2.0:status:ProxyCountExceeded"
	StatusRequestDenied = "urn:oasis:names:tc:SAML:2.0:status:RequestDenied"
	StatusRequestUnsupported = "urn:oasis:names:tc:SAML:2.0:status:RequestUnsupported"
	StatusRequestVersionDeprecated = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionDeprecated"
	StatusRequestVersionTooHigh = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooHigh"
	StatusRequestVersionTooLow = "urn:oasis:names:tc:SAML:2.0:status:RequestVersionTooLow"
	StatusResourceNotRecognized = "urn:oasis:names:tc:SAML:2.0:status:ResourceNotRecognized"
	StatusTooManyResponses = "urn:oasis:names:tc:SAML:2.0:status:TooManyResponses"
	StatusUnknownAttrProfile = "urn:oasis:names:tc:SAML:2.0:status:UnknownAttrProfile"
	StatusUnknownPrincipal = "urn:oasis:names:tc:SAML:2.0:status:UnknownPrincipal"
	StatusUnsupportedBinding = "urn:oasis:names:tc:SAML:2.0:status:UnsupportedBinding"
)
type StatusMessage struct {
	Value string
}
func (sm StatusMessage) Element() *etree.Element {
	el := etree.NewElement("samlp:StatusMessage")
	el.SetText(sm.Value)
	return el
}
type StatusDetail struct {
	Children []*etree.Element
}
func (sm StatusDetail) Element() *etree.Element {
	el := etree.NewElement("samlp:StatusDetail")
	for _, child := range sm.Children {
		el.AddChild(child)
	}
	return el
}
type Assertion struct {
	XMLName      xml.Name  `xml:"urn:oasis:names:tc:SAML:2.0:assertion Assertion"`
	ID           string    `xml:",attr"`
	IssueInstant time.Time `xml:",attr"`
	Version      string    `xml:",attr"`
	Issuer       Issuer    `xml:"urn:oasis:names:tc:SAML:2.0:assertion Issuer"`
	Signature    *etree.Element
	Subject      *Subject
	Conditions   *Conditions
	AuthnStatements []AuthnStatement `xml:"AuthnStatement"`
	AttributeStatements []AttributeStatement `xml:"AttributeStatement"`
}
func (a *Assertion) Element() *etree.Element {
	el := etree.NewElement("saml:Assertion")
	el.CreateAttr("xmlns:saml", "urn:oasis:names:tc:SAML:2.0:assertion")
	el.CreateAttr("Version", "2.0")
	el.CreateAttr("ID", a.ID)
	el.CreateAttr("IssueInstant", a.IssueInstant.Format(timeFormat))
	el.AddChild(a.Issuer.Element())
	if a.Signature != nil {
		el.AddChild(a.Signature)
	}
	if a.Subject != nil {
		el.AddChild(a.Subject.Element())
	}
	if a.Conditions != nil {
		el.AddChild(a.Conditions.Element())
	}
	for _, authnStatement := range a.AuthnStatements {
		el.AddChild(authnStatement.Element())
	}
	for _, attributeStatement := range a.AttributeStatements {
		el.AddChild(attributeStatement.Element())
	}
	err := etreeutils.TransformExcC14n(el, canonicalizerPrefixList)
	if err != nil {
		panic(err)
	}
	return el
}
func (a *Assertion) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias Assertion
	aux := &struct {
		IssueInstant RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(a),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	a.IssueInstant = time.Time(aux.IssueInstant)
	return nil
}
type Subject struct {
	XMLName xml.Name `xml:"urn:oasis:names:tc:SAML:2.0:assertion Subject"`
	NameID *NameID
	SubjectConfirmations []SubjectConfirmation `xml:"SubjectConfirmation"`
}
func (a *Subject) Element() *etree.Element {
	el := etree.NewElement("saml:Subject")
	if a.NameID != nil {
		el.AddChild(a.NameID.Element())
	}
	for _, v := range a.SubjectConfirmations {
		el.AddChild(v.Element())
	}
	return el
}
type NameID struct {
	NameQualifier   string `xml:",attr"`
	SPNameQualifier string `xml:",attr"`
	Format          string `xml:",attr"`
	SPProvidedID    string `xml:",attr"`
	Value           string `xml:",chardata"`
}
func (a *NameID) Element() *etree.Element {
	el := etree.NewElement("saml:NameID")
	if a.NameQualifier != "" {
		el.CreateAttr("NameQualifier", a.NameQualifier)
	}
	if a.SPNameQualifier != "" {
		el.CreateAttr("SPNameQualifier", a.SPNameQualifier)
	}
	if a.Format != "" {
		el.CreateAttr("Format", a.Format)
	}
	if a.SPProvidedID != "" {
		el.CreateAttr("SPProvidedID", a.SPProvidedID)
	}
	if a.Value != "" {
		el.SetText(a.Value)
	}
	return el
}
type SessionIndex struct {
	Value string `xml:",chardata"`
}
func (s *SessionIndex) Element() *etree.Element {
	el := etree.NewElement("samlp:SessionIndex")
	el.CreateAttr("xmlns:samlp", "urn:oasis:names:tc:SAML:2.0:protocol")
	if s.Value != "" {
		el.SetText(s.Value)
	}
	return el
}
type SubjectConfirmation struct {
	Method string `xml:",attr"`
	NameID *NameID
	SubjectConfirmationData *SubjectConfirmationData
}
func (a *SubjectConfirmation) Element() *etree.Element {
	el := etree.NewElement("saml:SubjectConfirmation")
	el.CreateAttr("Method", a.Method)
	if a.NameID != nil {
		el.AddChild(a.NameID.Element())
	}
	if a.SubjectConfirmationData != nil {
		el.AddChild(a.SubjectConfirmationData.Element())
	}
	return el
}
type SubjectConfirmationData struct {
	NotBefore    time.Time `xml:",attr"`
	NotOnOrAfter time.Time `xml:",attr"`
	Recipient    string    `xml:",attr"`
	InResponseTo string    `xml:",attr"`
	Address      string    `xml:",attr"`
}
func (s *SubjectConfirmationData) Element() *etree.Element {
	el := etree.NewElement("saml:SubjectConfirmationData")
	if !s.NotBefore.IsZero() {
		el.CreateAttr("NotBefore", s.NotBefore.Format(timeFormat))
	}
	if !s.NotOnOrAfter.IsZero() {
		el.CreateAttr("NotOnOrAfter", s.NotOnOrAfter.Format(timeFormat))
	}
	if s.Recipient != "" {
		el.CreateAttr("Recipient", s.Recipient)
	}
	if s.InResponseTo != "" {
		el.CreateAttr("InResponseTo", s.InResponseTo)
	}
	if s.Address != "" {
		el.CreateAttr("Address", s.Address)
	}
	return el
}
func (s *SubjectConfirmationData) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias SubjectConfirmationData
	aux := &struct {
		NotOnOrAfter RelaxedTime `xml:",attr"`
		*Alias
	}{
		NotOnOrAfter: RelaxedTime(s.NotOnOrAfter),
		Alias:        (*Alias)(s),
	}
	return e.EncodeElement(aux, start)
}
func (s *SubjectConfirmationData) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias SubjectConfirmationData
	aux := &struct {
		NotOnOrAfter RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(s),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	s.NotOnOrAfter = time.Time(aux.NotOnOrAfter)
	return nil
}
type Conditions struct {
	NotBefore            time.Time             `xml:",attr"`
	NotOnOrAfter         time.Time             `xml:",attr"`
	AudienceRestrictions []AudienceRestriction `xml:"AudienceRestriction"`
	OneTimeUse           *OneTimeUse
	ProxyRestriction     *ProxyRestriction
}
func (c *Conditions) Element() *etree.Element {
	el := etree.NewElement("saml:Conditions")
	if !c.NotBefore.IsZero() {
		el.CreateAttr("NotBefore", c.NotBefore.Format(timeFormat))
	}
	if !c.NotOnOrAfter.IsZero() {
		el.CreateAttr("NotOnOrAfter", c.NotOnOrAfter.Format(timeFormat))
	}
	for _, v := range c.AudienceRestrictions {
		el.AddChild(v.Element())
	}
	if c.OneTimeUse != nil {
		el.AddChild(c.OneTimeUse.Element())
	}
	if c.ProxyRestriction != nil {
		el.AddChild(c.ProxyRestriction.Element())
	}
	return el
}
func (c *Conditions) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	type Alias Conditions
	aux := &struct {
		NotBefore    RelaxedTime `xml:",attr"`
		NotOnOrAfter RelaxedTime `xml:",attr"`
		*Alias
	}{
		NotBefore:    RelaxedTime(c.NotBefore),
		NotOnOrAfter: RelaxedTime(c.NotOnOrAfter),
		Alias:        (*Alias)(c),
	}
	return e.EncodeElement(aux, start)
}
func (c *Conditions) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	type Alias Conditions
	aux := &struct {
		NotBefore    RelaxedTime `xml:",attr"`
		NotOnOrAfter RelaxedTime `xml:",attr"`
		*Alias
	}{
		Alias: (*Alias)(c),
	}
	if err := d.DecodeElement(&aux, &start); err != nil {
		return err
	}
	c.NotBefore = time.Time(aux.NotBefore)
	c.NotOnOrAfter = time.Time(aux.NotOnOrAfter)
	return nil
}
type AudienceRestriction struct {
	Audience Audience
}
func (a *AudienceRestriction) Element() *etree.Element {
	el := etree.NewElement("saml:AudienceRestriction")
	el.AddChild(a.Audience.Element())
	return el
}
type Audience struct {
	Value string `xml:",chardata"`
}
func (a *Audience) Element() *etree.Element {
	el := etree.NewElement("saml:Audience")
	el.SetText(a.Value)
	return el
}
type OneTimeUse struct{}
func (a *OneTimeUse) Element() *etree.Element {
	return etree.NewElement("saml:OneTimeUse")
}
type ProxyRestriction struct {
	Count     *int
	Audiences []Audience
}
func (a *ProxyRestriction) Element() *etree.Element {
	el := etree.NewElement("saml:ProxyRestriction")
	if a.Count != nil {
		el.CreateAttr("Count", strconv.Itoa(*a.Count))
	}
	for _, v := range a.Audiences {
		el.AddChild(v.Element())
	}
	return el
}
type AuthnStatement struct {
	AuthnInstant        time.Time  `xml:",attr"`
	SessionIndex        string     `xml:",attr"`
	SessionNotOnOrAfter *time.Time `xml:",attr,omitempty"`
	SubjectLocality     *SubjectLocality
	AuthnContext        AuthnContext
}
func (a *AuthnStatement) Element() *etree.Element {
	el := etree.NewElement("saml:AuthnStatement")
	el.CreateAttr("AuthnInstant", a.AuthnInstant.Format(timeFormat))
	if a.SessionIndex != "" {
		el.CreateAttr("SessionIndex", a.SessionIndex)
	}
	if a.SessionNotOnOrAfter != nil {
		el.CreateAttr("SessionNotOnOrAfter", a.SessionNotOnOrAfter.Format(timeFormat))
	}
	if a.SubjectLocality != nil {
		el.AddChild(a.SubjectLocality.Element())
	}
	el.AddChild(a.AuthnContext.Element())
	return el
}