Set fourth file version digit to signify rebuild.
[shibboleth/cpp-opensaml.git] / saml / saml2 / core / impl / Assertions20Impl.cpp
index 9c743c8..efdb49f 100644 (file)
 #include <xmltooling/util/XMLHelper.h>
 
 #include <ctime>
+#include <boost/lambda/bind.hpp>
+#include <boost/lambda/if.hpp>
+#include <boost/lambda/lambda.hpp>
 #include <xercesc/util/XMLUniDefs.hpp>
 
 using namespace opensaml::saml2;
-using namespace xmlencryption;
-using namespace xmlsignature;
 using namespace xmltooling;
 using namespace std;
 using xmlconstants::XSI_NS;
@@ -102,13 +103,16 @@ namespace opensaml {
             NameIDTypeImpl(const NameIDTypeImpl& src)
                     : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setNameQualifier(src.getNameQualifier());
-                setSPNameQualifier(src.getSPNameQualifier());
-                setFormat(src.getFormat());
-                setSPProvidedID(src.getSPProvidedID());
             }
 
-            IMPL_XMLOBJECT_CLONE(NameIDType);
+            void _clone(const NameIDTypeImpl& src) {
+                IMPL_CLONE_ATTRIB(NameQualifier);
+                IMPL_CLONE_ATTRIB(SPNameQualifier);
+                IMPL_CLONE_ATTRIB(Format);
+                IMPL_CLONE_ATTRIB(SPProvidedID);
+            }
+
+            IMPL_XMLOBJECT_CLONE_EX(NameIDType);
             IMPL_STRING_ATTRIB(NameQualifier);
             IMPL_STRING_ATTRIB(SPNameQualifier);
             IMPL_STRING_ATTRIB(Format);
@@ -141,10 +145,7 @@ namespace opensaml {
 
             NameIDImpl(const NameIDImpl& src) : AbstractXMLObject(src), NameIDTypeImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(NameID);
-            NameIDType* cloneNameIDType() const {
-                return new NameIDImpl(*this);
-            }
+            IMPL_XMLOBJECT_CLONE_EX(NameID);
         };
 
         class SAML_DLLLOCAL IssuerImpl : public virtual Issuer, public NameIDTypeImpl
@@ -157,14 +158,9 @@ namespace opensaml {
 
             IssuerImpl(const IssuerImpl& src) : AbstractXMLObject(src), NameIDTypeImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(Issuer);
-            NameIDType* cloneNameIDType() const {
-                return new IssuerImpl(*this);
-            }
+            IMPL_XMLOBJECT_CLONE_EX(Issuer);
         };
 
-        //TODO unit test for this
-        //  - need to test encryption/decryption too, or already done in xmltooling ?
         class SAML_DLLLOCAL EncryptedElementTypeImpl : public virtual EncryptedElementType,
             public AbstractComplexElement,
             public AbstractDOMCachingXMLObject,
@@ -193,17 +189,14 @@ namespace opensaml {
             EncryptedElementTypeImpl(const EncryptedElementTypeImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                if (src.getEncryptedData())
-                    setEncryptedData(src.getEncryptedData()->cloneEncryptedData());
-                VectorOf(EncryptedKey) v=getEncryptedKeys();
-                for (vector<EncryptedKey*>::const_iterator i=src.m_EncryptedKeys.begin(); i!=src.m_EncryptedKeys.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneEncryptedKey());
-                    }
-                }
             }
 
-            IMPL_XMLOBJECT_CLONE(EncryptedElementType);
+            void _clone(const EncryptedElementTypeImpl& src) {
+                IMPL_CLONE_TYPED_CHILD(EncryptedData);
+                IMPL_CLONE_TYPED_FOREIGN_CHILDREN(EncryptedKey,xmlencryption);
+            }
+
+            IMPL_XMLOBJECT_CLONE_EX(EncryptedElementType);
             IMPL_TYPED_FOREIGN_CHILD(EncryptedData,xmlencryption);
             IMPL_TYPED_FOREIGN_CHILDREN(EncryptedKey,xmlencryption,m_children.end());
 
@@ -225,10 +218,7 @@ namespace opensaml {
 
             EncryptedIDImpl(const EncryptedIDImpl& src) : AbstractXMLObject(src), EncryptedElementTypeImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(EncryptedID);
-            EncryptedElementType* cloneEncryptedElementType() const {
-                return new EncryptedIDImpl(*this);
-            }
+            IMPL_XMLOBJECT_CLONE_EX(EncryptedID);
         };
 
         class SAML_DLLLOCAL ConditionImpl : public virtual Condition, public AnyElementImpl
@@ -237,8 +227,7 @@ namespace opensaml {
             virtual ~ConditionImpl() {}
 
             ConditionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             ConditionImpl(const ConditionImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
 
@@ -255,23 +244,14 @@ namespace opensaml {
             virtual ~AudienceRestrictionImpl() {}
 
             AudienceRestrictionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             AudienceRestrictionImpl(const AudienceRestrictionImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                VectorOf(Audience) v=getAudiences();
-                for (vector<Audience*>::const_iterator i=src.m_Audiences.begin(); i!=src.m_Audiences.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneAudience());
-                    }
-                }
+                IMPL_CLONE_TYPED_CHILDREN(Audience);
             }
 
-            IMPL_XMLOBJECT_CLONE(AudienceRestriction);
-            Condition* cloneCondition() const {
-                return cloneAudienceRestriction();
-            }
+            IMPL_XMLOBJECT_CLONE2(AudienceRestriction,Condition);
             IMPL_TYPED_CHILDREN(Audience,m_children.end());
 
         protected:
@@ -291,17 +271,12 @@ namespace opensaml {
             virtual ~OneTimeUseImpl() {}
 
             OneTimeUseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             OneTimeUseImpl(const OneTimeUseImpl& src)
-                : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
-            }
+                : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {}
 
-            IMPL_XMLOBJECT_CLONE(OneTimeUse);
-            Condition* cloneCondition() const {
-                return cloneOneTimeUse();
-            }
+            IMPL_XMLOBJECT_CLONE2(OneTimeUse,Condition);
         };
 
         class SAML_DLLLOCAL ProxyRestrictionImpl : public virtual ProxyRestriction,
@@ -316,25 +291,15 @@ namespace opensaml {
             }
 
             ProxyRestrictionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-                m_Count=nullptr;
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Count(nullptr) {}
 
             ProxyRestrictionImpl(const ProxyRestrictionImpl& src)
-                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                setCount(src.m_Count);
-                VectorOf(Audience) v=getAudiences();
-                for (vector<Audience*>::const_iterator i=src.m_Audiences.begin(); i!=src.m_Audiences.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneAudience());
-                    }
-                }
+                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src), m_Count(nullptr) {
+                IMPL_CLONE_INTEGER_ATTRIB(Count);
+                IMPL_CLONE_TYPED_CHILDREN(Audience);
             }
 
-            IMPL_XMLOBJECT_CLONE(ProxyRestriction);
-            Condition* cloneCondition() const {
-                return cloneProxyRestriction();
-            }
+            IMPL_XMLOBJECT_CLONE2(ProxyRestriction,Condition);
             IMPL_TYPED_CHILDREN(Audience,m_children.end());
             IMPL_INTEGER_ATTRIB(Count);
 
@@ -375,6 +340,7 @@ namespace opensaml {
                 m_pos_EncryptedID=m_pos_NameID;
                 ++m_pos_EncryptedID;
             }
+
         public:
             virtual ~DelegateImpl() {
                 XMLString::release(&m_ConfirmationMethod);
@@ -389,14 +355,11 @@ namespace opensaml {
             DelegateImpl(const DelegateImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setConfirmationMethod(src.getConfirmationMethod());
-                setDelegationInstant(src.getDelegationInstant());
-                if (src.getBaseID())
-                    setBaseID(src.getBaseID()->cloneBaseID());
-                if (src.getNameID())
-                    setNameID(src.getNameID()->cloneNameID());
-                if (src.getEncryptedID())
-                    setEncryptedID(src.getEncryptedID()->cloneEncryptedID());
+                IMPL_CLONE_ATTRIB(ConfirmationMethod);
+                IMPL_CLONE_ATTRIB(DelegationInstant);
+                IMPL_CLONE_TYPED_CHILD(BaseID);
+                IMPL_CLONE_TYPED_CHILD(NameID);
+                IMPL_CLONE_TYPED_CHILD(EncryptedID);
             }
 
             IMPL_XMLOBJECT_CLONE(Delegate);
@@ -436,23 +399,14 @@ namespace opensaml {
             virtual ~DelegationRestrictionTypeImpl() {}
 
             DelegationRestrictionTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             DelegationRestrictionTypeImpl(const DelegationRestrictionTypeImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                VectorOf(Delegate) v=getDelegates();
-                for (vector<Delegate*>::const_iterator i=src.m_Delegates.begin(); i!=src.m_Delegates.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneDelegate());
-                    }
-                }
+                IMPL_CLONE_TYPED_CHILDREN(Delegate);
             }
 
-            IMPL_XMLOBJECT_CLONE(DelegationRestrictionType);
-            Condition* cloneCondition() const {
-                return cloneDelegationRestrictionType();
-            }
+            IMPL_XMLOBJECT_CLONE2(DelegationRestrictionType,Condition);
             IMPL_TYPED_CHILDREN(Delegate,m_children.end());
 
         protected:
@@ -471,6 +425,7 @@ namespace opensaml {
             void init() {
                 m_NotBefore=m_NotOnOrAfter=nullptr;
             }
+
         public:
             virtual ~ConditionsImpl() {
                 delete m_NotBefore;
@@ -485,36 +440,15 @@ namespace opensaml {
             ConditionsImpl(const ConditionsImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setNotBefore(src.getNotBefore());
-                setNotOnOrAfter(src.getNotOnOrAfter());
-
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        AudienceRestriction* arc=dynamic_cast<AudienceRestriction*>(*i);
-                        if (arc) {
-                            getAudienceRestrictions().push_back(arc->cloneAudienceRestriction());
-                            continue;
-                        }
-
-                        OneTimeUse* dncc=dynamic_cast<OneTimeUse*>(*i);
-                        if (dncc) {
-                            getOneTimeUses().push_back(dncc->cloneOneTimeUse());
-                            continue;
-                        }
-
-                        ProxyRestriction* prc=dynamic_cast<ProxyRestriction*>(*i);
-                        if (prc) {
-                            getProxyRestrictions().push_back(prc->cloneProxyRestriction());
-                            continue;
-                        }
-
-                        Condition* c=dynamic_cast<Condition*>(*i);
-                        if (c) {
-                            getConditions().push_back(c->cloneCondition());
-                            continue;
-                        }
-                    }
-                }
+                IMPL_CLONE_ATTRIB(NotBefore);
+                IMPL_CLONE_ATTRIB(NotOnOrAfter);
+
+                IMPL_CLONE_CHILDBAG_BEGIN;
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AudienceRestriction);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(OneTimeUse);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(ProxyRestriction);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(Condition);
+                IMPL_CLONE_CHILDBAG_END;
             }
 
             IMPL_XMLOBJECT_CLONE(Conditions);
@@ -574,11 +508,18 @@ namespace opensaml {
 
             SubjectConfirmationDataTypeImpl(const SubjectConfirmationDataTypeImpl& src) : AbstractXMLObject(src) {
                 init();
-                setNotBefore(src.getNotBefore());
-                setNotOnOrAfter(src.getNotOnOrAfter());
-                setRecipient(src.getRecipient());
-                setInResponseTo(src.getInResponseTo());
-                setAddress(src.getAddress());
+            }
+
+            void _clone(const SubjectConfirmationDataTypeImpl& src) {
+                IMPL_CLONE_ATTRIB(NotBefore);
+                IMPL_CLONE_ATTRIB(NotOnOrAfter);
+                IMPL_CLONE_ATTRIB(Recipient);
+                IMPL_CLONE_ATTRIB(InResponseTo);
+                IMPL_CLONE_ATTRIB(Address);
+            }
+
+            SubjectConfirmationDataType* cloneSubjectConfirmationDataType() const {
+                return dynamic_cast<SubjectConfirmationDataType*>(clone());
             }
 
             IMPL_DATETIME_ATTRIB(NotBefore,0);
@@ -612,18 +553,18 @@ namespace opensaml {
             virtual ~SubjectConfirmationDataImpl() {}
 
             SubjectConfirmationDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             SubjectConfirmationDataImpl(const SubjectConfirmationDataImpl& src)
-                    : AbstractXMLObject(src), SubjectConfirmationDataTypeImpl(src), AnyElementImpl(src) {
-            }
+                : AbstractXMLObject(src), SubjectConfirmationDataTypeImpl(src), AnyElementImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(SubjectConfirmationData);
-            SubjectConfirmationDataType* cloneSubjectConfirmationDataType() const {
-                return new SubjectConfirmationDataImpl(*this);
+            void _clone(const SubjectConfirmationDataImpl& src) {
+                SubjectConfirmationDataTypeImpl::_clone(src);
+                AnyElementImpl::_clone(src);
             }
 
+            IMPL_XMLOBJECT_CLONE_EX(SubjectConfirmationData);
+
             void setAttribute(const xmltooling::QName& qualifiedName, const XMLCh* value, bool ID=false) {
                 if (!qualifiedName.hasNamespaceURI()) {
                     if (XMLString::equals(qualifiedName.getLocalPart(),NOTBEFORE_ATTRIB_NAME)) {
@@ -678,23 +619,19 @@ namespace opensaml {
             virtual ~KeyInfoConfirmationDataTypeImpl() {}
 
             KeyInfoConfirmationDataTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             KeyInfoConfirmationDataTypeImpl(const KeyInfoConfirmationDataTypeImpl& src)
-                    : AbstractXMLObject(src), SubjectConfirmationDataTypeImpl(src), AbstractComplexElement(src),
-                        AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
-                VectorOf(KeyInfo) v=getKeyInfos();
-                for (vector<KeyInfo*>::const_iterator i=src.m_KeyInfos.begin(); i!=src.m_KeyInfos.end(); ++i)
-                    v.push_back((*i)->cloneKeyInfo());
-            }
+                : AbstractXMLObject(src), SubjectConfirmationDataTypeImpl(src), AbstractComplexElement(src),
+                    AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {}
 
-            IMPL_XMLOBJECT_CLONE(KeyInfoConfirmationDataType);
-            SubjectConfirmationDataType* cloneSubjectConfirmationDataType() const {
-                return new KeyInfoConfirmationDataTypeImpl(*this);
+            void _clone(const KeyInfoConfirmationDataTypeImpl& src) {
+                SubjectConfirmationDataTypeImpl::_clone(src);
+                IMPL_CLONE_TYPED_FOREIGN_CHILDREN(KeyInfo,xmlsignature);
             }
 
-            IMPL_TYPED_CHILDREN(KeyInfo,m_children.end());
+            IMPL_XMLOBJECT_CLONE_EX(KeyInfoConfirmationDataType);
+            IMPL_TYPED_FOREIGN_CHILDREN(KeyInfo,xmlsignature,m_children.end());
 
         public:
             void setAttribute(const xmltooling::QName& qualifiedName, const XMLCh* value, bool ID=false) {
@@ -730,7 +667,7 @@ namespace opensaml {
             }
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                PROC_TYPED_CHILDREN(KeyInfo,XMLSIG_NS,false);
+                PROC_TYPED_FOREIGN_CHILDREN(KeyInfo,xmlsignature,XMLSIG_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
 
@@ -763,6 +700,7 @@ namespace opensaml {
                 m_pos_SubjectConfirmationData=m_pos_EncryptedID;
                 ++m_pos_SubjectConfirmationData;
             }
+
         public:
             virtual ~SubjectConfirmationImpl() {
                 XMLString::release(&m_Method);
@@ -776,15 +714,11 @@ namespace opensaml {
             SubjectConfirmationImpl(const SubjectConfirmationImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setMethod(src.getMethod());
-                if (src.getBaseID())
-                    setBaseID(src.getBaseID()->cloneBaseID());
-                if (src.getNameID())
-                    setNameID(src.getNameID()->cloneNameID());
-                if (src.getEncryptedID())
-                    setEncryptedID(src.getEncryptedID()->cloneEncryptedID());
-                if (src.getSubjectConfirmationData())
-                    setSubjectConfirmationData(src.getSubjectConfirmationData()->clone());
+                IMPL_CLONE_ATTRIB(Method);
+                IMPL_CLONE_TYPED_CHILD(BaseID);
+                IMPL_CLONE_TYPED_CHILD(NameID);
+                IMPL_CLONE_TYPED_CHILD(EncryptedID);
+                IMPL_CLONE_XMLOBJECT_CHILD(SubjectConfirmationData);
             }
 
             IMPL_XMLOBJECT_CLONE(SubjectConfirmation);
@@ -832,6 +766,7 @@ namespace opensaml {
                 m_pos_EncryptedID=m_pos_NameID;
                 ++m_pos_EncryptedID;
             }
+
         public:
             virtual ~SubjectImpl() {}
 
@@ -843,18 +778,10 @@ namespace opensaml {
             SubjectImpl(const SubjectImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                if (src.getBaseID())
-                    setBaseID(src.getBaseID()->cloneBaseID());
-                if (src.getNameID())
-                    setNameID(src.getNameID()->cloneNameID());
-                if (src.getEncryptedID())
-                    setEncryptedID(src.getEncryptedID()->cloneEncryptedID());
-                VectorOf(SubjectConfirmation) v=getSubjectConfirmations();
-                for (vector<SubjectConfirmation*>::const_iterator i=src.m_SubjectConfirmations.begin(); i!=src.m_SubjectConfirmations.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneSubjectConfirmation());
-                    }
-                }
+                IMPL_CLONE_TYPED_CHILD(BaseID);
+                IMPL_CLONE_TYPED_CHILD(NameID);
+                IMPL_CLONE_TYPED_CHILD(EncryptedID);
+                IMPL_CLONE_TYPED_CHILDREN(SubjectConfirmation);
             }
 
             IMPL_XMLOBJECT_CLONE(Subject);
@@ -882,6 +809,7 @@ namespace opensaml {
             void init() {
                 m_Address=m_DNSName=nullptr;
             }
+
         public:
             virtual ~SubjectLocalityImpl() {
                 XMLString::release(&m_Address);
@@ -896,8 +824,8 @@ namespace opensaml {
             SubjectLocalityImpl(const SubjectLocalityImpl& src)
                     : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setAddress(src.getAddress());
-                setDNSName(src.getDNSName());
+                IMPL_CLONE_ATTRIB(Address);
+                IMPL_CLONE_ATTRIB(DNSName);
             }
 
             IMPL_XMLOBJECT_CLONE(SubjectLocality);
@@ -923,12 +851,11 @@ namespace opensaml {
             virtual ~StatementImpl() {}
 
             StatementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             StatementImpl(const StatementImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(Statement);
+            IMPL_XMLOBJECT_CLONE_EX(Statement);
         };
 
         //TODO need unit test for this
@@ -938,13 +865,11 @@ namespace opensaml {
             virtual ~AuthnContextDeclImpl() {}
 
             AuthnContextDeclImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
-            AuthnContextDeclImpl(const AuthnContextDeclImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {
-            }
+            AuthnContextDeclImpl(const AuthnContextDeclImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(AuthnContextDecl);
+            IMPL_XMLOBJECT_CLONE_EX(AuthnContextDecl);
         };
 
         class SAML_DLLLOCAL AuthnContextImpl : public virtual AuthnContext,
@@ -966,6 +891,7 @@ namespace opensaml {
                 m_pos_AuthnContextDeclRef=m_pos_AuthnContextDecl;
                 ++m_pos_AuthnContextDeclRef;
             }
+
         public:
             virtual ~AuthnContextImpl() {}
 
@@ -977,18 +903,10 @@ namespace opensaml {
             AuthnContextImpl(const AuthnContextImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                if (src.getAuthnContextClassRef())
-                    setAuthnContextClassRef(src.getAuthnContextClassRef()->cloneAuthnContextClassRef());
-                if (src.getAuthnContextDecl())
-                    setAuthnContextDecl(src.getAuthnContextDecl()->clone());
-                if (src.getAuthnContextDeclRef())
-                    setAuthnContextDeclRef(src.getAuthnContextDeclRef()->cloneAuthnContextDeclRef());
-                VectorOf(AuthenticatingAuthority) v=getAuthenticatingAuthoritys();
-                for (vector<AuthenticatingAuthority*>::const_iterator i=src.m_AuthenticatingAuthoritys.begin(); i!=src.m_AuthenticatingAuthoritys.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneAuthenticatingAuthority());
-                    }
-                }
+                IMPL_CLONE_TYPED_CHILD(AuthnContextClassRef);
+                IMPL_CLONE_XMLOBJECT_CHILD(AuthnContextDecl);
+                IMPL_CLONE_TYPED_CHILD(AuthnContextDeclRef);
+                IMPL_CLONE_TYPED_CHILDREN(AuthenticatingAuthority);
             }
 
             IMPL_XMLOBJECT_CLONE(AuthnContext);
@@ -1025,6 +943,7 @@ namespace opensaml {
                 m_pos_AuthnContext=m_pos_SubjectLocality;
                 ++m_pos_AuthnContext;
             }
+
         public:
             virtual ~AuthnStatementImpl() {
                 delete m_AuthnInstant;
@@ -1040,19 +959,14 @@ namespace opensaml {
             AuthnStatementImpl(const AuthnStatementImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setAuthnInstant(src.getAuthnInstant());
-                setSessionIndex(src.getSessionIndex());
-                setSessionNotOnOrAfter(src.getSessionNotOnOrAfter());
-                if (src.getSubjectLocality())
-                    setSubjectLocality(src.getSubjectLocality()->cloneSubjectLocality());
-                if (src.getAuthnContext())
-                    setAuthnContext(src.getAuthnContext()->cloneAuthnContext());
+                IMPL_CLONE_ATTRIB(AuthnInstant);
+                IMPL_CLONE_ATTRIB(SessionIndex);
+                IMPL_CLONE_ATTRIB(SessionNotOnOrAfter);
+                IMPL_CLONE_TYPED_CHILD(SubjectLocality);
+                IMPL_CLONE_TYPED_CHILD(AuthnContext);
             }
 
-            IMPL_XMLOBJECT_CLONE(AuthnStatement);
-            Statement* cloneStatement() const {
-                return cloneAuthnStatement();
-            }
+            IMPL_XMLOBJECT_CLONE2(AuthnStatement,Statement);
             IMPL_DATETIME_ATTRIB(AuthnInstant,0);
             IMPL_STRING_ATTRIB(SessionIndex);
             IMPL_DATETIME_ATTRIB(SessionNotOnOrAfter,SAMLTIME_MAX);
@@ -1092,12 +1006,11 @@ namespace opensaml {
             }
 
             ActionImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Namespace(nullptr) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Namespace(nullptr) {}
 
             ActionImpl(const ActionImpl& src)
-                    : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
-                setNamespace(src.getNamespace());
+                    : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_Namespace(nullptr) {
+                IMPL_CLONE_ATTRIB(Namespace);
             }
 
             IMPL_XMLOBJECT_CLONE(Action);
@@ -1124,38 +1037,16 @@ namespace opensaml {
             virtual ~EvidenceImpl() {}
 
             EvidenceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             EvidenceImpl(const EvidenceImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        AssertionIDRef* ref=dynamic_cast<AssertionIDRef*>(*i);
-                        if (ref) {
-                            getAssertionIDRefs().push_back(ref->cloneAssertionIDRef());
-                            continue;
-                        }
-
-                        AssertionURIRef* uri=dynamic_cast<AssertionURIRef*>(*i);
-                        if (uri) {
-                            getAssertionURIRefs().push_back(uri->cloneAssertionURIRef());
-                            continue;
-                        }
-
-                        Assertion* assertion=dynamic_cast<Assertion*>(*i);
-                        if (assertion) {
-                            getAssertions().push_back(assertion->cloneAssertion());
-                            continue;
-                        }
-
-                        EncryptedAssertion* enc=dynamic_cast<EncryptedAssertion*>(*i);
-                        if (enc) {
-                            getEncryptedAssertions().push_back(enc->cloneEncryptedAssertion());
-                            continue;
-                        }
-                    }
-                }
+                IMPL_CLONE_CHILDBAG_BEGIN;
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AssertionIDRef);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AssertionURIRef);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(Assertion);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(EncryptedAssertion);
+                IMPL_CLONE_CHILDBAG_END;
             }
 
             IMPL_XMLOBJECT_CLONE(Evidence);
@@ -1187,6 +1078,7 @@ namespace opensaml {
                 m_children.push_back(nullptr);
                 m_pos_Evidence=m_children.begin();
             }
+
         public:
             virtual ~AuthzDecisionStatementImpl() {
                 XMLString::release(&m_Resource);
@@ -1201,22 +1093,13 @@ namespace opensaml {
             AuthzDecisionStatementImpl(const AuthzDecisionStatementImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setResource(src.getResource());
-                setDecision(src.getDecision());
-                if (src.getEvidence())
-                    setEvidence(src.getEvidence()->cloneEvidence());
-                VectorOf(Action) v=getActions();
-                for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneAction());
-                    }
-                }
+                IMPL_CLONE_ATTRIB(Resource);
+                IMPL_CLONE_ATTRIB(Decision);
+                IMPL_CLONE_TYPED_CHILD(Evidence);
+                IMPL_CLONE_TYPED_CHILDREN(Action);
             }
 
-            IMPL_XMLOBJECT_CLONE(AuthzDecisionStatement);
-            Statement* cloneStatement() const {
-                return cloneAuthzDecisionStatement();
-            }
+            IMPL_XMLOBJECT_CLONE2(AuthzDecisionStatement,Statement);
             IMPL_STRING_ATTRIB(Resource);
             IMPL_STRING_ATTRIB(Decision);
             IMPL_TYPED_CHILD(Evidence);
@@ -1247,13 +1130,11 @@ namespace opensaml {
             virtual ~AttributeValueImpl() {}
 
             AttributeValueImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
-            AttributeValueImpl(const AttributeValueImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {
-            }
+            AttributeValueImpl(const AttributeValueImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(AttributeValue);
+            IMPL_XMLOBJECT_CLONE_EX(AttributeValue);
         };
 
 
@@ -1267,6 +1148,7 @@ namespace opensaml {
             void init() {
                 m_Name=m_NameFormat=m_FriendlyName=nullptr;
             }
+
         public:
             virtual ~AttributeImpl() {
                 XMLString::release(&m_Name);
@@ -1283,15 +1165,10 @@ namespace opensaml {
                     : AbstractXMLObject(src), AbstractComplexElement(src),
                         AbstractAttributeExtensibleXMLObject(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setName(src.getName());
-                setNameFormat(src.getNameFormat());
-                setFriendlyName(src.getFriendlyName());
-                VectorOf(XMLObject) v=getAttributeValues();
-                for (vector<XMLObject*>::const_iterator i=src.m_AttributeValues.begin(); i!=src.m_AttributeValues.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->clone());
-                    }
-                }
+                IMPL_CLONE_ATTRIB(Name);
+                IMPL_CLONE_ATTRIB(NameFormat);
+                IMPL_CLONE_ATTRIB(FriendlyName);
+                IMPL_CLONE_XMLOBJECT_CHILDREN(AttributeValue);
             }
 
             IMPL_XMLOBJECT_CLONE(Attribute);
@@ -1335,7 +1212,6 @@ namespace opensaml {
             }
         };
 
-        //TODO unit test for this
         class SAML_DLLLOCAL EncryptedAttributeImpl : public virtual EncryptedAttribute, public EncryptedElementTypeImpl
         {
         public:
@@ -1346,10 +1222,7 @@ namespace opensaml {
 
             EncryptedAttributeImpl(const EncryptedAttributeImpl& src) : AbstractXMLObject(src), EncryptedElementTypeImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(EncryptedAttribute);
-            EncryptedElementType* cloneEncryptedElementType() const {
-                return new EncryptedAttributeImpl(*this);
-            }
+            IMPL_XMLOBJECT_CLONE_EX(EncryptedAttribute);
         };
 
         class SAML_DLLLOCAL AttributeStatementImpl : public virtual AttributeStatement,
@@ -1362,32 +1235,17 @@ namespace opensaml {
             virtual ~AttributeStatementImpl() {}
 
             AttributeStatementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             AttributeStatementImpl(const AttributeStatementImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        Attribute* attribute=dynamic_cast<Attribute*>(*i);
-                        if (attribute) {
-                            getAttributes().push_back(attribute->cloneAttribute());
-                            continue;
-                        }
-
-                        EncryptedAttribute* enc=dynamic_cast<EncryptedAttribute*>(*i);
-                        if (enc) {
-                            getEncryptedAttributes().push_back(enc->cloneEncryptedAttribute());
-                            continue;
-                        }
-                    }
-                }
+                IMPL_CLONE_CHILDBAG_BEGIN;
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(Attribute);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(EncryptedAttribute);
+                IMPL_CLONE_CHILDBAG_END;
             }
 
-            IMPL_XMLOBJECT_CLONE(AttributeStatement);
-            Statement* cloneStatement() const {
-                return cloneAttributeStatement();
-            }
+            IMPL_XMLOBJECT_CLONE2(AttributeStatement,Statement);
             IMPL_TYPED_CHILDREN(Attribute, m_children.end());
             IMPL_TYPED_CHILDREN(EncryptedAttribute, m_children.end());
 
@@ -1409,40 +1267,17 @@ namespace opensaml {
             virtual ~AdviceImpl() {}
 
             AdviceImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
             AdviceImpl(const AdviceImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        AssertionIDRef* ref=dynamic_cast<AssertionIDRef*>(*i);
-                        if (ref) {
-                            getAssertionIDRefs().push_back(ref->cloneAssertionIDRef());
-                            continue;
-                        }
-
-                        AssertionURIRef* uri=dynamic_cast<AssertionURIRef*>(*i);
-                        if (uri) {
-                            getAssertionURIRefs().push_back(uri->cloneAssertionURIRef());
-                            continue;
-                        }
-
-                        Assertion* assertion=dynamic_cast<Assertion*>(*i);
-                        if (assertion) {
-                            getAssertions().push_back(assertion->cloneAssertion());
-                            continue;
-                        }
-
-                        EncryptedAssertion* enc=dynamic_cast<EncryptedAssertion*>(*i);
-                        if (enc) {
-                            getEncryptedAssertions().push_back(enc->cloneEncryptedAssertion());
-                            continue;
-                        }
-
-                        getUnknownXMLObjects().push_back((*i)->clone());
-                    }
-                }
+                IMPL_CLONE_CHILDBAG_BEGIN;
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AssertionIDRef);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AssertionURIRef);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(Assertion);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(EncryptedAssertion);
+                    IMPL_CLONE_XMLOBJECT_CHILD_IN_BAG(UnknownXMLObject);
+                IMPL_CLONE_CHILDBAG_END;
             }
 
             IMPL_XMLOBJECT_CLONE(Advice);
@@ -1470,7 +1305,6 @@ namespace opensaml {
             }
         };
 
-        //TODO unit test for this
         class SAML_DLLLOCAL EncryptedAssertionImpl : public virtual EncryptedAssertion, public EncryptedElementTypeImpl
         {
         public:
@@ -1481,10 +1315,7 @@ namespace opensaml {
 
             EncryptedAssertionImpl(const EncryptedAssertionImpl& src) : AbstractXMLObject(src), EncryptedElementTypeImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(EncryptedAssertion);
-            EncryptedElementType* cloneEncryptedElementType() const {
-                return new EncryptedAssertionImpl(*this);
-            }
+            IMPL_XMLOBJECT_CLONE_EX(EncryptedAssertion);
         };
 
         class SAML_DLLLOCAL AssertionImpl : public virtual Assertion,
@@ -1517,6 +1348,7 @@ namespace opensaml {
                 m_pos_Advice=m_pos_Conditions;
                 ++m_pos_Advice;
             }
+
         public:
             virtual ~AssertionImpl() {
                 XMLString::release(&m_ID);
@@ -1532,59 +1364,33 @@ namespace opensaml {
             AssertionImpl(const AssertionImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setVersion(src.getVersion());
-                setID(src.getID());
-                setIssueInstant(src.getIssueInstant());
-                if (src.getIssuer())
-                    setIssuer(src.getIssuer()->cloneIssuer());
-                if (src.getSignature())
-                    setSignature(src.getSignature()->cloneSignature());
-                if (src.getSubject())
-                    setSubject(src.getSubject()->cloneSubject());
-                if (src.getConditions())
-                    setConditions(src.getConditions()->cloneConditions());
-                if (src.getAdvice())
-                    setAdvice(src.getAdvice()->cloneAdvice());
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        AuthnStatement* authst=dynamic_cast<AuthnStatement*>(*i);
-                        if (authst) {
-                            getAuthnStatements().push_back(authst->cloneAuthnStatement());
-                            continue;
-                        }
-
-                        AttributeStatement* attst=dynamic_cast<AttributeStatement*>(*i);
-                        if (attst) {
-                            getAttributeStatements().push_back(attst->cloneAttributeStatement());
-                            continue;
-                        }
-
-                        AuthzDecisionStatement* authzst=dynamic_cast<AuthzDecisionStatement*>(*i);
-                        if (authzst) {
-                            getAuthzDecisionStatements().push_back(authzst->cloneAuthzDecisionStatement());
-                            continue;
-                        }
-
-                        Statement* st=dynamic_cast<Statement*>(*i);
-                        if (st) {
-                            getStatements().push_back(st->cloneStatement());
-                            continue;
-                        }
-                    }
-                }
+                IMPL_CLONE_ATTRIB(Version);
+                IMPL_CLONE_ATTRIB(ID);
+                IMPL_CLONE_ATTRIB(IssueInstant);
+                IMPL_CLONE_TYPED_CHILD(Issuer);
+                IMPL_CLONE_TYPED_CHILD(Signature);
+                IMPL_CLONE_TYPED_CHILD(Subject);
+                IMPL_CLONE_TYPED_CHILD(Conditions);
+                IMPL_CLONE_TYPED_CHILD(Advice);
+                IMPL_CLONE_CHILDBAG_BEGIN;
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AuthnStatement);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AttributeStatement);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(AuthzDecisionStatement);
+                    IMPL_CLONE_TYPED_CHILD_IN_BAG(Statement);
+                IMPL_CLONE_CHILDBAG_END;
             }
 
             //IMPL_TYPED_CHILD(Signature);
             // Need customized setter.
         protected:
-            Signature* m_Signature;
+            xmlsignature::Signature* m_Signature;
             list<XMLObject*>::iterator m_pos_Signature;
         public:
-            Signature* getSignature() const {
+            xmlsignature::Signature* getSignature() const {
                 return m_Signature;
             }
 
-            void setSignature(Signature* sig) {
+            void setSignature(xmlsignature::Signature* sig) {
                 prepareForAssignment(m_Signature,sig);
                 *m_pos_Signature=m_Signature=sig;
                 // Sync content reference back up.
@@ -1627,7 +1433,7 @@ namespace opensaml {
 
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
                 PROC_TYPED_CHILD(Issuer,SAML20_NS,false);
-                PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
+                PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLSIG_NS,false);
                 PROC_TYPED_CHILD(Subject,SAML20_NS,false);
                 PROC_TYPED_CHILD(Conditions,SAML20_NS,false);
                 PROC_TYPED_CHILD(Advice,SAML20_NS,false);