https://issues.shibboleth.net/jira/browse/SSPCPP-469
[shibboleth/cpp-opensaml.git] / saml / saml2 / core / impl / Protocols20Impl.cpp
index a0a4599..95e75cd 100644 (file)
@@ -1,17 +1,21 @@
-/*
- *  Copyright 2001-2010 Internet2
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
+/**
+ * Licensed to the University Corporation for Advanced Internet
+ * Development, Inc. (UCAID) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for
+ * additional information regarding copyright ownership.
  *
- *     http://www.apache.org/licenses/LICENSE-2.0
+ * UCAID licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the
+ * License at
  *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
  */
 
 /**
 #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::saml2p;
-using namespace opensaml::saml2;
-using namespace xmlsignature;
-using namespace xmlencryption;
 using namespace xmltooling;
 using namespace std;
 using xmlconstants::XMLSIG_NS;
@@ -67,7 +71,27 @@ namespace opensaml {
 
         DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,RespondTo);
 
-        //TODO need unit test for this, using objects from another namespace
+        class SAML_DLLLOCAL AsynchronousImpl : public virtual Asynchronous,
+            public AbstractSimpleElement,
+            public AbstractDOMCachingXMLObject,
+            public AbstractXMLObjectMarshaller,
+            public AbstractXMLObjectUnmarshaller
+        {
+        public:
+            virtual ~AsynchronousImpl() {}
+
+            AsynchronousImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
+
+            AsynchronousImpl(const AsynchronousImpl& src)
+                : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {}
+
+            IMPL_XMLOBJECT_CLONE(Asynchronous);
+
+        protected:
+            // has no attributes or children
+        };
+
         class SAML_DLLLOCAL ExtensionsImpl : public virtual Extensions,
              public AbstractComplexElement,
              public AbstractDOMCachingXMLObject,
@@ -78,14 +102,11 @@ namespace opensaml {
             virtual ~ExtensionsImpl() {}
     
             ExtensionsImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
-            }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
                 
             ExtensionsImpl(const ExtensionsImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                VectorOf(XMLObject) v=getUnknownXMLObjects();
-                for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
-                    v.push_back((*i)->clone());
+                IMPL_CLONE_XMLOBJECT_CHILDREN(UnknownXMLObject);
             }
             
             IMPL_XMLOBJECT_CLONE(Extensions);
@@ -116,72 +137,68 @@ namespace opensaml {
                 m_children.push_back(nullptr);
                 m_pos_StatusCode=m_children.begin();
             }
-            public:
-                virtual ~StatusCodeImpl() {
-                    XMLString::release(&m_Value);
-                }
 
-                StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-                {
-                        init();
-                }
+        public:
+            virtual ~StatusCodeImpl() {
+                XMLString::release(&m_Value);
+            }
 
-                StatusCodeImpl(const StatusCodeImpl& src)
-                        : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                    init();
-                    setValue(src.getValue());
-                    if (src.getStatusCode())
-                        setStatusCode(src.getStatusCode()->cloneStatusCode());
-                }
+            StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+                init();
+            }
 
-                IMPL_XMLOBJECT_CLONE(StatusCode);
-                IMPL_STRING_ATTRIB(Value);
-                IMPL_TYPED_CHILD(StatusCode);
+            StatusCodeImpl(const StatusCodeImpl& src)
+                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
+                init();
+                IMPL_CLONE_ATTRIB(Value);
+                IMPL_CLONE_TYPED_CHILD(StatusCode);
+            }
 
-            protected:
-                void marshallAttributes(DOMElement* domElement) const {
-                    MARSHALL_STRING_ATTRIB(Value,VALUE,nullptr);
-                }
+            IMPL_XMLOBJECT_CLONE(StatusCode);
+            IMPL_STRING_ATTRIB(Value);
+            IMPL_TYPED_CHILD(StatusCode);
 
-                void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                    PROC_TYPED_CHILD(StatusCode,SAML20P_NS,false);
-                    AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
-                }
+        protected:
+            void marshallAttributes(DOMElement* domElement) const {
+                MARSHALL_STRING_ATTRIB(Value,VALUE,nullptr);
+            }
 
-                void processAttribute(const DOMAttr* attribute) {
-                    PROC_STRING_ATTRIB(Value,VALUE,nullptr);
-                    AbstractXMLObjectUnmarshaller::processAttribute(attribute);
-                }
+            void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+                PROC_TYPED_CHILD(StatusCode,SAML20P_NS,false);
+                AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
+            }
+
+            void processAttribute(const DOMAttr* attribute) {
+                PROC_STRING_ATTRIB(Value,VALUE,nullptr);
+                AbstractXMLObjectUnmarshaller::processAttribute(attribute);
+            }
         };
 
-        //TODO need unit tests for non-SAML namespace children
         class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
             public AbstractComplexElement,
             public AbstractDOMCachingXMLObject,
             public AbstractXMLObjectMarshaller,
             public AbstractXMLObjectUnmarshaller
         {
-            public:
-                virtual ~StatusDetailImpl() {}
+        public:
+            virtual ~StatusDetailImpl() {}
 
-                StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) { }
+            StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
-                StatusDetailImpl(const StatusDetailImpl& src)
-                        : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
-                    VectorOf(XMLObject) v=getUnknownXMLObjects();
-                    for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
-                        v.push_back((*i)->clone());
-                }
+            StatusDetailImpl(const StatusDetailImpl& src)
+                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
+                IMPL_CLONE_XMLOBJECT_CHILDREN(UnknownXMLObject);
+            }
 
-                IMPL_XMLOBJECT_CLONE(StatusDetail);
-                IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
+            IMPL_XMLOBJECT_CLONE(StatusDetail);
+            IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
 
-            protected:
-                void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
-                    getUnknownXMLObjects().push_back(childXMLObject);
-                }
+        protected:
+            void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
+                getUnknownXMLObjects().push_back(childXMLObject);
+            }
         };
 
 
@@ -204,23 +221,20 @@ namespace opensaml {
                 m_pos_StatusDetail=m_pos_StatusMessage;
                 ++m_pos_StatusDetail;
             }
+
         public:
-            virtual ~StatusImpl() { }
+            virtual ~StatusImpl() {}
     
             StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
                     : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
-            StatusImpl(const StatusImpl& src)
-                    : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
+            StatusImpl(const StatusImpl& src) : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                if (src.getStatusCode())
-                    setStatusCode(src.getStatusCode()->cloneStatusCode());
-                if (src.getStatusMessage())
-                    setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
-                if (src.getStatusDetail())
-                    setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
+                IMPL_CLONE_TYPED_CHILD(StatusCode);
+                IMPL_CLONE_TYPED_CHILD(StatusMessage);
+                IMPL_CLONE_TYPED_CHILD(StatusDetail);
             }
             
             IMPL_XMLOBJECT_CLONE(Status);
@@ -228,15 +242,28 @@ namespace opensaml {
             IMPL_TYPED_CHILD(StatusMessage);
             IMPL_TYPED_CHILD(StatusDetail);
     
+            // Base class methods.
+            const XMLCh* getTopStatus() const {
+                return getStatusCode() ? getStatusCode()->getValue() : nullptr;
+            }
+            const XMLCh* getSubStatus() const {
+                const StatusCode* sc = getStatusCode() ? getStatusCode()->getStatusCode() : nullptr;
+                return sc ? sc->getValue() : nullptr;
+            }
+            bool hasAdditionalStatus() const {
+                return (getStatusCode() && getStatusCode()->getStatusCode() && getStatusCode()->getStatusCode()->getStatusCode());
+            }
+            const XMLCh* getMessage() const {
+                return getStatusMessage() ? getStatusMessage()->getMessage() : nullptr;
+            }
+
         protected:
-    
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
                 PROC_TYPED_CHILD(StatusCode,SAML20P_NS,false);
                 PROC_TYPED_CHILD(StatusMessage,SAML20P_NS,false);
                 PROC_TYPED_CHILD(StatusDetail,SAML20P_NS,false);
                 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
             }
-    
         };
 
 
@@ -264,10 +291,12 @@ namespace opensaml {
                 m_pos_Extensions=m_pos_Signature;
                 ++m_pos_Extensions;
             }
+
         protected:
             RequestAbstractTypeImpl() {
                 init();
             }
+
         public:
             virtual ~RequestAbstractTypeImpl() {
                 XMLString::release(&m_ID);
@@ -285,36 +314,40 @@ namespace opensaml {
             RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setID(src.getID());
-                setVersion(src.getVersion());
-                setIssueInstant(src.getIssueInstant());
-                setDestination(src.getDestination());
-                setConsent(src.getConsent());
-                if (src.getIssuer())
-                    setIssuer(src.getIssuer()->cloneIssuer());
-                if (src.getSignature())
-                    setSignature(src.getSignature()->cloneSignature());
-                if (src.getExtensions())
-                    setExtensions(src.getExtensions()->cloneExtensions());
+            }
+
+            void _clone(const RequestAbstractTypeImpl& src) {
+                IMPL_CLONE_ATTRIB(ID);
+                IMPL_CLONE_ATTRIB(Version);
+                IMPL_CLONE_ATTRIB(IssueInstant);
+                IMPL_CLONE_ATTRIB(Destination);
+                IMPL_CLONE_ATTRIB(Consent);
+                IMPL_CLONE_TYPED_CHILD(Issuer);
+                IMPL_CLONE_TYPED_CHILD(Signature);
+                IMPL_CLONE_TYPED_CHILD(Extensions);
             }
             
             //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.
                 if (m_Signature)
                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
             }
+
+            RequestAbstractType* cloneRequestAbstractType() const {
+                return dynamic_cast<RequestAbstractType*>(clone());
+            }
             
             IMPL_STRING_ATTRIB(Version);
             IMPL_ID_ATTRIB_EX(ID,ID,nullptr);
@@ -325,6 +358,11 @@ namespace opensaml {
             IMPL_TYPED_CHILD(Extensions);
     
         protected:
+            void prepareForMarshalling() const {
+                if (m_Signature)
+                    declareNonVisibleNamespaces();
+            }
+
             void marshallAttributes(DOMElement* domElement) const {
                 if (!m_Version)
                     const_cast<RequestAbstractTypeImpl*>(this)->m_Version=XMLString::transcode("2.0");
@@ -362,26 +400,19 @@ namespace opensaml {
         class SAML_DLLLOCAL AssertionIDRequestImpl : public virtual AssertionIDRequest, public RequestAbstractTypeImpl
         {
         public:
-            virtual ~AssertionIDRequestImpl() { }
+            virtual ~AssertionIDRequestImpl() {}
     
             AssertionIDRequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) { }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
                 
-            AssertionIDRequestImpl(const AssertionIDRequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
-                VectorOf(AssertionIDRef) v=getAssertionIDRefs();
-                for (vector<AssertionIDRef*>::const_iterator i=src.m_AssertionIDRefs.begin(); i!=src.m_AssertionIDRefs.end(); i++) {
-                    if (*i) {                               
-                        v.push_back((*i)->cloneAssertionIDRef());
-                    }
-                }
+            AssertionIDRequestImpl(const AssertionIDRequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {}
 
+            void _clone(const AssertionIDRequestImpl& src) {
+                RequestAbstractTypeImpl::_clone(src);
+                IMPL_CLONE_TYPED_FOREIGN_CHILDREN(AssertionIDRef,saml2);
             }
             
-            IMPL_XMLOBJECT_CLONE(AssertionIDRequest);
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneAssertionIDRequest();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(AssertionIDRequest);
             IMPL_TYPED_FOREIGN_CHILDREN(AssertionIDRef,saml2,m_children.end());
     
         protected:
@@ -393,32 +424,39 @@ namespace opensaml {
 
         class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery, public RequestAbstractTypeImpl
         {
-            void init()
-            {
+            void init() {
                 m_Subject = nullptr;
                 m_children.push_back(nullptr);
                 m_pos_Subject = m_pos_Extensions;
                 ++m_pos_Subject;
             }
+
         protected:
             SubjectQueryImpl() {
                 init();
             }
+
         public:
-            virtual ~SubjectQueryImpl() { }
+            virtual ~SubjectQueryImpl() {}
     
             SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            { 
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             SubjectQueryImpl(const SubjectQueryImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
                 init();
-                if (src.getSubject())
-                    setSubject(src.getSubject()->cloneSubject());
+            }
+
+            void _clone(const SubjectQueryImpl& src) {
+                RequestAbstractTypeImpl::_clone(src);
+                IMPL_CLONE_TYPED_CHILD(Subject);
             }
             
+            SubjectQuery* cloneSubjectQuery() const {
+                return dynamic_cast<SubjectQuery*>(clone());
+            }
+
             IMPL_TYPED_FOREIGN_CHILD(Subject,saml2);
     
         protected:
@@ -428,7 +466,6 @@ namespace opensaml {
             }
         };
 
-
         class SAML_DLLLOCAL RequestedAuthnContextImpl : public virtual RequestedAuthnContext,
             public AbstractComplexElement,
             public AbstractDOMCachingXMLObject,
@@ -438,6 +475,7 @@ namespace opensaml {
             void init() {
                 m_Comparison=nullptr;
             }
+
         public:
             virtual ~RequestedAuthnContextImpl() {
                 XMLString::release(&m_Comparison);
@@ -451,22 +489,11 @@ namespace opensaml {
             RequestedAuthnContextImpl(const RequestedAuthnContextImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setComparison(src.getComparison());
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        AuthnContextClassRef* classref=dynamic_cast<AuthnContextClassRef*>(*i);
-                        if (classref) {
-                            getAuthnContextClassRefs().push_back(classref->cloneAuthnContextClassRef());
-                            continue;
-                        }
-
-                        AuthnContextDeclRef* declref=dynamic_cast<AuthnContextDeclRef*>(*i);
-                        if (declref) {
-                            getAuthnContextDeclRefs().push_back(declref->cloneAuthnContextDeclRef());
-                            continue;
-                        }
-                    }
-                }
+                IMPL_CLONE_ATTRIB(Comparison);
+                IMPL_CLONE_CHILDBAG_BEGIN;
+                    IMPL_CLONE_TYPED_FOREIGN_CHILD_IN_BAG(AuthnContextClassRef,saml2);
+                    IMPL_CLONE_TYPED_FOREIGN_CHILD_IN_BAG(AuthnContextDeclRef,saml2);
+                IMPL_CLONE_CHILDBAG_END;
             }
             
             IMPL_XMLOBJECT_CLONE(RequestedAuthnContext);
@@ -491,7 +518,6 @@ namespace opensaml {
             }
         };
 
-
         class SAML_DLLLOCAL AuthnQueryImpl : public virtual AuthnQuery, public SubjectQueryImpl
         {
             void init() {
@@ -502,32 +528,28 @@ namespace opensaml {
                 ++m_pos_RequestedAuthnContext;
                 
             }
+
         public:
             virtual ~AuthnQueryImpl() {
                 XMLString::release(&m_SessionIndex);
             }
     
             AuthnQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             AuthnQueryImpl(const AuthnQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
                 init();
-                setSessionIndex(src.getSessionIndex());
-                if (src.getRequestedAuthnContext())
-                    setRequestedAuthnContext(src.getRequestedAuthnContext()->cloneRequestedAuthnContext());
-            }
-            
-            IMPL_XMLOBJECT_CLONE(AuthnQuery);
-            SubjectQuery* cloneSubjectQuery() const {
-                return cloneAuthnQuery();
-            }
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneAuthnQuery();
             }
 
+            void _clone(const AuthnQueryImpl& src) {
+                SubjectQueryImpl::_clone(src);
+                IMPL_CLONE_ATTRIB(SessionIndex);
+                IMPL_CLONE_TYPED_CHILD(RequestedAuthnContext);
+            }
+            
+            IMPL_XMLOBJECT_CLONE_EX(AuthnQuery);
             IMPL_STRING_ATTRIB(SessionIndex);
             IMPL_TYPED_CHILD(RequestedAuthnContext);
     
@@ -550,32 +572,19 @@ namespace opensaml {
         class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
         {
         public:
-            virtual ~AttributeQueryImpl() { }
+            virtual ~AttributeQueryImpl() {}
     
             AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) { }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
                 
-            AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        Attribute* attrib=dynamic_cast<Attribute*>(*i);
-                        if (attrib) {
-                            getAttributes().push_back(attrib->cloneAttribute());
-                            continue;
-                        }
-                    }
-                }
+            AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {}
 
+            void _clone(const AttributeQueryImpl& src) {
+                SubjectQueryImpl::_clone(src);
+                IMPL_CLONE_TYPED_FOREIGN_CHILDREN(Attribute,saml2);
             }
             
-            IMPL_XMLOBJECT_CLONE(AttributeQuery);
-            SubjectQuery* cloneSubjectQuery() const {
-                return cloneAttributeQuery();
-            }
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneAttributeQuery();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(AttributeQuery);
             IMPL_TYPED_FOREIGN_CHILDREN(Attribute,saml2,m_children.end());
     
         protected:
@@ -592,9 +601,9 @@ namespace opensaml {
                 m_Evidence=nullptr;
                 m_children.push_back(nullptr);
                 m_pos_Evidence=m_pos_Subject;
-                ++m_pos_Evidence;
-                
+                ++m_pos_Evidence;   
             }
+
         public:
             virtual ~AuthzDecisionQueryImpl() {
                 XMLString::release(&m_Resource);
@@ -607,28 +616,16 @@ namespace opensaml {
                 
             AuthzDecisionQueryImpl(const AuthzDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
                 init();
-                setResource(src.getResource());
-                if (src.getEvidence())
-                    setEvidence(src.getEvidence()->cloneEvidence());
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        Action* action=dynamic_cast<Action*>(*i);
-                        if (action) {
-                            getActions().push_back(action->cloneAction());
-                            continue;
-                        }
-                    }
-                }
-            }
-            
-            IMPL_XMLOBJECT_CLONE(AuthzDecisionQuery);
-            SubjectQuery* cloneSubjectQuery() const {
-                return cloneAuthzDecisionQuery();
-            }
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneAuthzDecisionQuery();
             }
 
+            void _clone(const AuthzDecisionQueryImpl& src) {
+                SubjectQueryImpl::_clone(src);
+                IMPL_CLONE_ATTRIB(Resource);
+                IMPL_CLONE_TYPED_CHILD(Evidence);
+                IMPL_CLONE_TYPED_FOREIGN_CHILDREN(Action,saml2);
+            }
+            
+            IMPL_XMLOBJECT_CLONE_EX(AuthzDecisionQuery);
             IMPL_STRING_ATTRIB(Resource);
             IMPL_TYPED_FOREIGN_CHILDREN(Action,saml2,m_pos_Evidence);
             IMPL_TYPED_FOREIGN_CHILD(Evidence,saml2);
@@ -661,45 +658,44 @@ namespace opensaml {
                 m_SPNameQualifier=nullptr;
                 m_AllowCreate=XML_BOOL_NULL;
             }
-            public:
-                virtual ~NameIDPolicyImpl()
-                {
-                    XMLString::release(&m_Format);
-                    XMLString::release(&m_SPNameQualifier);
-                }
 
-                NameIDPolicyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-                {
-                        init();
-                }
+        public:
+            virtual ~NameIDPolicyImpl() {
+                XMLString::release(&m_Format);
+                XMLString::release(&m_SPNameQualifier);
+            }
 
-                NameIDPolicyImpl(const NameIDPolicyImpl& src)
-                        : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
-                    init();
-                    setFormat(src.getFormat());
-                    setSPNameQualifier(src.getSPNameQualifier());
-                    AllowCreate(m_AllowCreate);
-                }
+            NameIDPolicyImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+                init();
+            }
 
-                IMPL_XMLOBJECT_CLONE(NameIDPolicy);
-                IMPL_STRING_ATTRIB(Format);
-                IMPL_STRING_ATTRIB(SPNameQualifier);
-                IMPL_BOOLEAN_ATTRIB(AllowCreate);
+            NameIDPolicyImpl(const NameIDPolicyImpl& src)
+                    : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
+                init();
+                IMPL_CLONE_ATTRIB(Format);
+                IMPL_CLONE_ATTRIB(SPNameQualifier);
+                IMPL_CLONE_BOOLEAN_ATTRIB(AllowCreate);
+            }
 
-            protected:
-                void marshallAttributes(DOMElement* domElement) const {
-                    MARSHALL_STRING_ATTRIB(Format,FORMAT,nullptr);
-                    MARSHALL_STRING_ATTRIB(SPNameQualifier,SPNAMEQUALIFIER,nullptr);
-                    MARSHALL_BOOLEAN_ATTRIB(AllowCreate,ALLOWCREATE,nullptr);
-                }
+            IMPL_XMLOBJECT_CLONE(NameIDPolicy);
+            IMPL_STRING_ATTRIB(Format);
+            IMPL_STRING_ATTRIB(SPNameQualifier);
+            IMPL_BOOLEAN_ATTRIB(AllowCreate);
 
-                void processAttribute(const DOMAttr* attribute) {
-                    PROC_STRING_ATTRIB(Format,FORMAT,nullptr);
-                    PROC_STRING_ATTRIB(SPNameQualifier,SPNAMEQUALIFIER,nullptr);
-                    PROC_BOOLEAN_ATTRIB(AllowCreate,ALLOWCREATE,nullptr);
-                    AbstractXMLObjectUnmarshaller::processAttribute(attribute);
-                }
+        protected:
+            void marshallAttributes(DOMElement* domElement) const {
+                MARSHALL_STRING_ATTRIB(Format,FORMAT,nullptr);
+                MARSHALL_STRING_ATTRIB(SPNameQualifier,SPNAMEQUALIFIER,nullptr);
+                MARSHALL_BOOLEAN_ATTRIB(AllowCreate,ALLOWCREATE,nullptr);
+            }
+
+            void processAttribute(const DOMAttr* attribute) {
+                PROC_STRING_ATTRIB(Format,FORMAT,nullptr);
+                PROC_STRING_ATTRIB(SPNameQualifier,SPNAMEQUALIFIER,nullptr);
+                PROC_BOOLEAN_ATTRIB(AllowCreate,ALLOWCREATE,nullptr);
+                AbstractXMLObjectUnmarshaller::processAttribute(attribute);
+            }
         };
 
         class SAML_DLLLOCAL IDPEntryImpl : public virtual IDPEntry,
@@ -713,46 +709,44 @@ namespace opensaml {
                 m_Name=nullptr;
                 m_Loc=nullptr;
             }
-            public:
-                virtual ~IDPEntryImpl()
-                {
-                    XMLString::release(&m_ProviderID);
-                    XMLString::release(&m_Name);
-                    XMLString::release(&m_Loc);
-                }
 
-                IDPEntryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-                {
-                        init();
-                }
+        public:
+            virtual ~IDPEntryImpl() {
+                XMLString::release(&m_ProviderID);
+                XMLString::release(&m_Name);
+                XMLString::release(&m_Loc);
+            }
 
-                IDPEntryImpl(const IDPEntryImpl& src)
-                        : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
-                    init();
-                    setProviderID(src.getProviderID());
-                    setName(src.getName());
-                    setLoc(src.getLoc());
-                }
+            IDPEntryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
+                init();
+            }
 
-                IMPL_XMLOBJECT_CLONE(IDPEntry);
-                IMPL_STRING_ATTRIB(ProviderID);
-                IMPL_STRING_ATTRIB(Name);
-                IMPL_STRING_ATTRIB(Loc);
+            IDPEntryImpl(const IDPEntryImpl& src) : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
+                init();
+                IMPL_CLONE_ATTRIB(ProviderID);
+                IMPL_CLONE_ATTRIB(Name);
+                IMPL_CLONE_ATTRIB(Loc);
+            }
 
-            protected:
-                void marshallAttributes(DOMElement* domElement) const {
-                    MARSHALL_STRING_ATTRIB(ProviderID,PROVIDERID,nullptr);
-                    MARSHALL_STRING_ATTRIB(Name,NAME,nullptr);
-                    MARSHALL_STRING_ATTRIB(Loc,LOC,nullptr);
-                }
+            IMPL_XMLOBJECT_CLONE(IDPEntry);
+            IMPL_STRING_ATTRIB(ProviderID);
+            IMPL_STRING_ATTRIB(Name);
+            IMPL_STRING_ATTRIB(Loc);
 
-                void processAttribute(const DOMAttr* attribute) {
-                    PROC_STRING_ATTRIB(ProviderID,PROVIDERID,nullptr);
-                    PROC_STRING_ATTRIB(Name,NAME,nullptr);
-                    PROC_STRING_ATTRIB(Loc,LOC,nullptr);
-                    AbstractXMLObjectUnmarshaller::processAttribute(attribute);
-                }
+        protected:
+            void marshallAttributes(DOMElement* domElement) const {
+                MARSHALL_STRING_ATTRIB(ProviderID,PROVIDERID,nullptr);
+                MARSHALL_STRING_ATTRIB(Name,NAME,nullptr);
+                MARSHALL_STRING_ATTRIB(Loc,LOC,nullptr);
+            }
+
+            void processAttribute(const DOMAttr* attribute) {
+                PROC_STRING_ATTRIB(ProviderID,PROVIDERID,nullptr);
+                PROC_STRING_ATTRIB(Name,NAME,nullptr);
+                PROC_STRING_ATTRIB(Loc,LOC,nullptr);
+                AbstractXMLObjectUnmarshaller::processAttribute(attribute);
+            }
         };
 
         class SAML_DLLLOCAL IDPListImpl : public virtual IDPList,
@@ -765,31 +759,21 @@ namespace opensaml {
                 m_GetComplete=nullptr;
                 m_children.push_back(nullptr);
                 m_pos_GetComplete=m_children.begin();
-                
             }
+
         public:
-            virtual ~IDPListImpl() { }
+            virtual ~IDPListImpl() {}
     
             IDPListImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             IDPListImpl(const IDPListImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                if (src.getGetComplete())
-                    setGetComplete(src.getGetComplete()->cloneGetComplete());
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        IDPEntry* entry=dynamic_cast<IDPEntry*>(*i);
-                        if (entry) {
-                            getIDPEntrys().push_back(entry->cloneIDPEntry());
-                            continue;
-                        }
-                    }
-                }
+                IMPL_CLONE_TYPED_CHILD(GetComplete);
+                IMPL_CLONE_TYPED_CHILDREN(IDPEntry);
             }
             
             IMPL_XMLOBJECT_CLONE(IDPList);
@@ -816,34 +800,24 @@ namespace opensaml {
                 m_IDPList=nullptr;
                 m_children.push_back(nullptr);
                 m_pos_IDPList=m_children.begin();
-                
             }
+
         public:
             virtual ~ScopingImpl() {
                 XMLString::release(&m_ProxyCount); 
             }
     
             ScopingImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             ScopingImpl(const ScopingImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setProxyCount(m_ProxyCount);
-                if (src.getIDPList())
-                    setIDPList(src.getIDPList()->cloneIDPList());
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        RequesterID* reqid =dynamic_cast<RequesterID*>(*i);
-                        if (reqid) {
-                            getRequesterIDs().push_back(reqid->cloneRequesterID());
-                            continue;
-                        }
-                    }
-                }
+                IMPL_CLONE_INTEGER_ATTRIB(ProxyCount);
+                IMPL_CLONE_TYPED_CHILD(IDPList);
+                IMPL_CLONE_TYPED_CHILDREN(RequesterID);
             }
             
             IMPL_XMLOBJECT_CLONE(Scoping);
@@ -853,7 +827,7 @@ namespace opensaml {
     
         protected:
             void marshallAttributes(DOMElement* domElement) const {
-                    MARSHALL_INTEGER_ATTRIB(ProxyCount,PROXYCOUNT,nullptr);
+                MARSHALL_INTEGER_ATTRIB(ProxyCount,PROXYCOUNT,nullptr);
             }
     
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
@@ -899,8 +873,8 @@ namespace opensaml {
                 ++m_pos_RequestedAuthnContext;
                 m_pos_Scoping=m_pos_RequestedAuthnContext;
                 ++m_pos_Scoping;
-                
             }
+
         public:
             virtual ~AuthnRequestImpl() {
                 XMLString::release(&m_ProtocolBinding);
@@ -911,38 +885,31 @@ namespace opensaml {
             }
     
             AuthnRequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             AuthnRequestImpl(const AuthnRequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
                 init();
+            }
 
-                ForceAuthn(m_ForceAuthn);
-                IsPassive(m_IsPassive);
-                setProtocolBinding(src.getProtocolBinding());
-                setAssertionConsumerServiceIndex(m_AssertionConsumerServiceIndex);
-                setAssertionConsumerServiceURL(src.getAssertionConsumerServiceURL());
-                setAttributeConsumingServiceIndex(m_AttributeConsumingServiceIndex);
-                setProviderName(src.getProviderName());
-
-                if (src.getSubject())
-                    setSubject(src.getSubject()->cloneSubject());
-                if (src.getNameIDPolicy())
-                    setNameIDPolicy(src.getNameIDPolicy()->cloneNameIDPolicy());
-                if (src.getConditions())
-                    setConditions(src.getConditions()->cloneConditions());
-                if (src.getRequestedAuthnContext())
-                    setRequestedAuthnContext(src.getRequestedAuthnContext()->cloneRequestedAuthnContext());
-                if (src.getScoping())
-                    setScoping(src.getScoping()->cloneScoping());
+            void _clone(const AuthnRequestImpl& src) {
+                RequestAbstractTypeImpl::_clone(src);
+                IMPL_CLONE_BOOLEAN_ATTRIB(ForceAuthn);
+                IMPL_CLONE_BOOLEAN_ATTRIB(IsPassive);
+                IMPL_CLONE_ATTRIB(ProtocolBinding);
+                IMPL_CLONE_INTEGER_ATTRIB(AssertionConsumerServiceIndex);
+                IMPL_CLONE_ATTRIB(AssertionConsumerServiceURL);
+                IMPL_CLONE_INTEGER_ATTRIB(AttributeConsumingServiceIndex);
+                IMPL_CLONE_ATTRIB(ProviderName);
+                IMPL_CLONE_TYPED_CHILD(Subject);
+                IMPL_CLONE_TYPED_CHILD(NameIDPolicy);
+                IMPL_CLONE_TYPED_CHILD(Conditions);
+                IMPL_CLONE_TYPED_CHILD(RequestedAuthnContext);
+                IMPL_CLONE_TYPED_CHILD(Scoping);
             }
             
-            IMPL_XMLOBJECT_CLONE(AuthnRequest);
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneAuthnRequest();
-            }
+            IMPL_XMLOBJECT_CLONE_EX(AuthnRequest);
 
             IMPL_BOOLEAN_ATTRIB(ForceAuthn);
             IMPL_BOOLEAN_ATTRIB(IsPassive);
@@ -1019,10 +986,12 @@ namespace opensaml {
                 m_pos_Status=m_pos_Extensions;
                 ++m_pos_Status;
             }
+
         protected:
             StatusResponseTypeImpl() {
                 init();
             }
+
         public:
             virtual ~StatusResponseTypeImpl() {
                 XMLString::release(&m_ID);
@@ -1034,41 +1003,39 @@ namespace opensaml {
             }
     
             StatusResponseTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             StatusResponseTypeImpl(const StatusResponseTypeImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                setID(src.getID());
-                setInResponseTo(src.getInResponseTo());
-                setVersion(src.getVersion());
-                setIssueInstant(src.getIssueInstant());
-                setDestination(src.getDestination());
-                setConsent(src.getConsent());
-                if (src.getIssuer())
-                    setIssuer(src.getIssuer()->cloneIssuer());
-                if (src.getSignature())
-                    setSignature(src.getSignature()->cloneSignature());
-                if (src.getExtensions())
-                    setExtensions(src.getExtensions()->cloneExtensions());
-                if (src.getStatus())
-                    setStatus(src.getStatus()->cloneStatus());
+            }
+
+            void _clone(const StatusResponseTypeImpl& src) {
+                IMPL_CLONE_ATTRIB(ID);
+                IMPL_CLONE_ATTRIB(InResponseTo);
+                IMPL_CLONE_ATTRIB(Version);
+                IMPL_CLONE_ATTRIB(IssueInstant);
+                IMPL_CLONE_ATTRIB(Destination);
+                IMPL_CLONE_ATTRIB(Consent);
+                IMPL_CLONE_TYPED_CHILD(Issuer);
+                IMPL_CLONE_TYPED_CHILD(Signature);
+                IMPL_CLONE_TYPED_CHILD(Extensions);
+                IMPL_CLONE_TYPED_CHILD(Status);
             }
             
             //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.
@@ -1076,6 +1043,10 @@ namespace opensaml {
                     m_Signature->setContentReference(new opensaml::ContentReference(*this));
             }
             
+            StatusResponseType* cloneStatusResponseType() const {
+                return dynamic_cast<StatusResponseType*>(clone());
+            }
+
             IMPL_STRING_ATTRIB(Version);
             IMPL_ID_ATTRIB_EX(ID,ID,nullptr);
             IMPL_STRING_ATTRIB(InResponseTo);
@@ -1087,6 +1058,11 @@ namespace opensaml {
             IMPL_TYPED_CHILD(Status);
     
         protected:
+            void prepareForMarshalling() const {
+                if (m_Signature)
+                    declareNonVisibleNamespaces();
+            }
+
             void marshallAttributes(DOMElement* domElement) const {
                 if (!m_Version)
                     const_cast<StatusResponseTypeImpl*>(this)->m_Version=XMLString::transcode("2.0");
@@ -1126,34 +1102,22 @@ namespace opensaml {
         class SAML_DLLLOCAL ResponseImpl : public virtual Response, public StatusResponseTypeImpl
         {
         public:
-            virtual ~ResponseImpl() { }
+            virtual ~ResponseImpl() {}
     
             ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) { }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
                 
-            ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        saml2::Assertion* assertion=dynamic_cast<saml2::Assertion*>(*i);
-                        if (assertion) {
-                            getAssertions().push_back(assertion->cloneAssertion());
-                            continue;
-                        }
-                        EncryptedAssertion* encAssertion=dynamic_cast<EncryptedAssertion*>(*i);
-                        if (encAssertion) {
-                            getEncryptedAssertions().push_back(encAssertion->cloneEncryptedAssertion());
-                            continue;
-                        }
-                    }
-                }
+            ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {}
 
+            void _clone(const ResponseImpl& src) {
+                StatusResponseTypeImpl::_clone(src);
+                IMPL_CLONE_CHILDBAG_BEGIN;
+                    IMPL_CLONE_TYPED_FOREIGN_CHILD_IN_BAG(Assertion,saml2);
+                    IMPL_CLONE_TYPED_FOREIGN_CHILD_IN_BAG(EncryptedAssertion,saml2);
+                IMPL_CLONE_CHILDBAG_END;
             }
             
-            IMPL_XMLOBJECT_CLONE(Response);
-            StatusResponseType* cloneStatusResponseType() const {
-                return cloneResponse();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(Response);
             IMPL_TYPED_FOREIGN_CHILDREN(Assertion,saml2,m_children.end());
             IMPL_TYPED_FOREIGN_CHILDREN(EncryptedAssertion,saml2,m_children.end());
     
@@ -1173,26 +1137,25 @@ namespace opensaml {
                 m_pos_Artifact=m_pos_Extensions;
                 ++m_pos_Artifact;
             }
+
         public:
-            virtual ~ArtifactResolveImpl() { }
+            virtual ~ArtifactResolveImpl() {}
     
             ArtifactResolveImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            { 
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             ArtifactResolveImpl(const ArtifactResolveImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
                 init();
-                if(src.getArtifact())
-                    setArtifact(src.getArtifact()->cloneArtifact());
-            }
-            
-            IMPL_XMLOBJECT_CLONE(ArtifactResolve);
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneArtifactResolve();
             }
 
+            void _clone(const ArtifactResolveImpl& src) {
+                RequestAbstractTypeImpl::_clone(src);
+                IMPL_CLONE_TYPED_CHILD(Artifact);
+            }
+            
+            IMPL_XMLOBJECT_CLONE_EX(ArtifactResolve);
             IMPL_TYPED_CHILD(Artifact);
     
         protected:
@@ -1210,40 +1173,35 @@ namespace opensaml {
                 m_pos_Payload=m_pos_Status;
                 ++m_pos_Payload;
             }
+
         public:
-            virtual ~ArtifactResponseImpl() { }
+            virtual ~ArtifactResponseImpl() {}
     
             ArtifactResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             ArtifactResponseImpl(const ArtifactResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {
                 init();
-                if (src.getPayload())
-                    setPayload(getPayload()->clone());
+            }
 
+            void _clone(const ArtifactResponseImpl& src) {
+                StatusResponseTypeImpl::_clone(src);
+                IMPL_CLONE_XMLOBJECT_CHILD(Payload);
             }
             
-            IMPL_XMLOBJECT_CLONE(ArtifactResponse);
-            StatusResponseType* cloneStatusResponseType() const {
-                return cloneArtifactResponse();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(ArtifactResponse);
             IMPL_XMLOBJECT_CHILD(Payload);
     
         protected:
             void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
                 // These are valid elements for the parent StatusResponseType, so don't process these.
                 // If not one of these, then it must be the payload.
-                if (
-                    ! XMLHelper::isNodeNamed(root,SAML20_NS,saml2::Issuer::LOCAL_NAME) &&
-                    ! XMLHelper::isNodeNamed(root,XMLSIG_NS,xmlsignature::Signature::LOCAL_NAME) &&
-                    ! XMLHelper::isNodeNamed(root,SAML20P_NS,saml2p::Extensions::LOCAL_NAME) &&
-                    ! XMLHelper::isNodeNamed(root,SAML20P_NS,saml2p::Status::LOCAL_NAME)
-                   )
-                {
+                if (!XMLHelper::isNodeNamed(root,SAML20_NS,saml2::Issuer::LOCAL_NAME) &&
+                    !XMLHelper::isNodeNamed(root,XMLSIG_NS,xmlsignature::Signature::LOCAL_NAME) &&
+                    !XMLHelper::isNodeNamed(root,SAML20P_NS,saml2p::Extensions::LOCAL_NAME) &&
+                    !XMLHelper::isNodeNamed(root,SAML20P_NS,saml2p::Status::LOCAL_NAME)) {
                     setPayload(childXMLObject);
                     return;
                 }
@@ -1265,8 +1223,7 @@ namespace opensaml {
             }
             
         protected:
-            NewEncryptedIDImpl()
-            {
+            NewEncryptedIDImpl() {
                 init();
             }
             
@@ -1274,29 +1231,18 @@ namespace opensaml {
             virtual ~NewEncryptedIDImpl() {}
     
             NewEncryptedIDImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             NewEncryptedIDImpl(const NewEncryptedIDImpl& src)
                     : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
                 init();
-                if (src.getEncryptedData())
-                    setEncryptedData(src.getEncryptedData()->cloneEncryptedData());
-                VectorOf(xmlencryption::EncryptedKey) v=getEncryptedKeys();
-                for (vector<xmlencryption::EncryptedKey*>::const_iterator i=src.m_EncryptedKeys.begin(); i!=src.m_EncryptedKeys.end(); i++) {
-                    if (*i) {
-                        v.push_back((*i)->cloneEncryptedKey());
-                    }
-                }
+                IMPL_CLONE_TYPED_CHILD(EncryptedData);
+                IMPL_CLONE_TYPED_FOREIGN_CHILDREN(EncryptedKey,xmlencryption);
             }
     
-            IMPL_XMLOBJECT_CLONE(NewEncryptedID);
-            EncryptedElementType* cloneEncryptedElementType() const {
-                return new NewEncryptedIDImpl(*this);
-            }
-
+            IMPL_XMLOBJECT_CLONE2(NewEncryptedID,EncryptedElementType);
             IMPL_TYPED_FOREIGN_CHILD(EncryptedData,xmlencryption);
             IMPL_TYPED_FOREIGN_CHILDREN(EncryptedKey,xmlencryption,m_children.end());
     
@@ -1314,20 +1260,19 @@ namespace opensaml {
             public AbstractXMLObjectMarshaller,
             public AbstractXMLObjectUnmarshaller
         {
-            public:
-                virtual ~TerminateImpl() { }
+        public:
+            virtual ~TerminateImpl() {}
 
-                TerminateImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) { }
+            TerminateImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
 
-                TerminateImpl(const TerminateImpl& src)
-                    : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {
-                }
+            TerminateImpl(const TerminateImpl& src)
+                : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src) {}
 
-                IMPL_XMLOBJECT_CLONE(Terminate);
+            IMPL_XMLOBJECT_CLONE(Terminate);
 
-            protected:
-                // has no attributes or children
+        protected:
+            // has no attributes or children
         };
 
         class SAML_DLLLOCAL ManageNameIDRequestImpl : public virtual ManageNameIDRequest, public RequestAbstractTypeImpl
@@ -1353,38 +1298,30 @@ namespace opensaml {
                 ++m_pos_NewEncryptedID;
                 m_pos_Terminate=m_pos_NewEncryptedID;
                 ++m_pos_Terminate;
-                
             }
+
         public:
-            virtual ~ManageNameIDRequestImpl() { }
+            virtual ~ManageNameIDRequestImpl() {}
     
             ManageNameIDRequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             ManageNameIDRequestImpl(const ManageNameIDRequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
                 init();
+            }
 
-                if (src.getNameID())
-                    setNameID(src.getNameID()->cloneNameID());
-                if (src.getEncryptedID())
-                    setEncryptedID(src.getEncryptedID()->cloneEncryptedID());
-                if (src.getNewID())
-                    setNewID(src.getNewID()->cloneNewID());
-                if (src.getNewEncryptedID())
-                    setNewEncryptedID(src.getNewEncryptedID()->cloneNewEncryptedID());
-                if (src.getTerminate())
-                    setTerminate(src.getTerminate()->cloneTerminate());
-
+            void _clone(const ManageNameIDRequestImpl& src) {
+                RequestAbstractTypeImpl::_clone(src);
+                IMPL_CLONE_TYPED_CHILD(NameID);
+                IMPL_CLONE_TYPED_CHILD(EncryptedID);
+                IMPL_CLONE_TYPED_CHILD(NewID);
+                IMPL_CLONE_TYPED_CHILD(NewEncryptedID);
+                IMPL_CLONE_TYPED_CHILD(Terminate);
             }
             
-            IMPL_XMLOBJECT_CLONE(ManageNameIDRequest);
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneManageNameIDRequest();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(ManageNameIDRequest);
             IMPL_TYPED_FOREIGN_CHILD(NameID,saml2);
             IMPL_TYPED_FOREIGN_CHILD(EncryptedID,saml2);
             IMPL_TYPED_CHILD(NewID);
@@ -1405,18 +1342,14 @@ namespace opensaml {
         class SAML_DLLLOCAL ManageNameIDResponseImpl : public virtual ManageNameIDResponse, public StatusResponseTypeImpl
         {
         public:
-            virtual ~ManageNameIDResponseImpl() { }
+            virtual ~ManageNameIDResponseImpl() {}
 
             ManageNameIDResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) { }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
             
-            ManageNameIDResponseImpl(const ManageNameIDResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {
-            }
+            ManageNameIDResponseImpl(const ManageNameIDResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(ManageNameIDResponse);
-            StatusResponseType* cloneStatusResponseType() const {
-                return cloneManageNameIDResponse();
-            }
+            IMPL_XMLOBJECT_CLONE_EX(ManageNameIDResponse);
         };
 
         class SAML_DLLLOCAL LogoutRequestImpl : public virtual LogoutRequest, public RequestAbstractTypeImpl
@@ -1424,7 +1357,6 @@ namespace opensaml {
             void init() {
                 m_Reason=nullptr;
                 m_NotOnOrAfter=nullptr;
-
                 m_BaseID=nullptr;
                 m_NameID=nullptr;
                 m_EncryptedID=nullptr;
@@ -1437,8 +1369,8 @@ namespace opensaml {
                 ++m_pos_NameID;
                 m_pos_EncryptedID=m_pos_NameID;
                 ++m_pos_EncryptedID;
-                
             }
+
         public:
             virtual ~LogoutRequestImpl() {
                 XMLString::release(&m_Reason);
@@ -1446,40 +1378,25 @@ namespace opensaml {
             }
     
             LogoutRequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             LogoutRequestImpl(const LogoutRequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
                 init();
+            }
 
-                setReason(src.getReason());
-                setNotOnOrAfter(src.getNotOnOrAfter());
-
-                if (src.getBaseID())
-                    setBaseID(src.getBaseID()->cloneBaseID());
-                if (src.getNameID())
-                    setNameID(src.getNameID()->cloneNameID());
-                if (src.getEncryptedID())
-                    setEncryptedID(src.getEncryptedID()->cloneEncryptedID());
-
-                for (list<XMLObject*>::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) {
-                    if (*i) {
-                        SessionIndex* si = dynamic_cast<SessionIndex*>(*i);
-                        if (si) {
-                            getSessionIndexs().push_back(si->cloneSessionIndex());
-                            continue;
-                        }
-                    }
-                }
+            void _clone(const LogoutRequestImpl& src) {
+                RequestAbstractTypeImpl::_clone(src);
+                IMPL_CLONE_ATTRIB(Reason);
+                IMPL_CLONE_ATTRIB(NotOnOrAfter);
+                IMPL_CLONE_TYPED_CHILD(BaseID);
+                IMPL_CLONE_TYPED_CHILD(NameID);
+                IMPL_CLONE_TYPED_CHILD(EncryptedID);
+                IMPL_CLONE_TYPED_CHILDREN(SessionIndex);
             }
             
-            IMPL_XMLOBJECT_CLONE(LogoutRequest);
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneLogoutRequest();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(LogoutRequest);
             IMPL_STRING_ATTRIB(Reason);
             IMPL_DATETIME_ATTRIB(NotOnOrAfter,SAMLTIME_MAX);
             IMPL_TYPED_FOREIGN_CHILD(BaseID,saml2);
@@ -1511,18 +1428,14 @@ namespace opensaml {
         class SAML_DLLLOCAL LogoutResponseImpl : public virtual LogoutResponse, public StatusResponseTypeImpl
         {
         public:
-            virtual ~LogoutResponseImpl() { }
+            virtual ~LogoutResponseImpl() {}
 
             LogoutResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType) { }
+                : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
             
-            LogoutResponseImpl(const LogoutResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {
-            }
+            LogoutResponseImpl(const LogoutResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {}
 
-            IMPL_XMLOBJECT_CLONE(LogoutResponse);
-            StatusResponseType* cloneStatusResponseType() const {
-                return cloneLogoutResponse();
-            }
+            IMPL_XMLOBJECT_CLONE_EX(LogoutResponse);
         };
 
 
@@ -1545,36 +1458,29 @@ namespace opensaml {
                 ++m_pos_EncryptedID;
                 m_pos_NameIDPolicy=m_pos_EncryptedID;
                 ++m_pos_NameIDPolicy;
-                
             }
+
         public:
-            virtual ~NameIDMappingRequestImpl() { }
+            virtual ~NameIDMappingRequestImpl() {}
     
             NameIDMappingRequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             NameIDMappingRequestImpl(const NameIDMappingRequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
                 init();
+            }
 
-                if (src.getBaseID())
-                    setBaseID(src.getBaseID()->cloneBaseID());
-                if (src.getNameID())
-                    setNameID(src.getNameID()->cloneNameID());
-                if (src.getEncryptedID())
-                    setEncryptedID(src.getEncryptedID()->cloneEncryptedID());
-                if (src.getNameIDPolicy())
-                    setNameIDPolicy(src.getNameIDPolicy()->cloneNameIDPolicy());
-
+            void _clone(const NameIDMappingRequestImpl& src) {
+                RequestAbstractTypeImpl::_clone(src);
+                IMPL_CLONE_TYPED_CHILD(BaseID);
+                IMPL_CLONE_TYPED_CHILD(NameID);
+                IMPL_CLONE_TYPED_CHILD(EncryptedID);
+                IMPL_CLONE_TYPED_CHILD(NameIDPolicy);
             }
             
-            IMPL_XMLOBJECT_CLONE(NameIDMappingRequest);
-            RequestAbstractType* cloneRequestAbstractType() const {
-                return cloneNameIDMappingRequest();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(NameIDMappingRequest);
             IMPL_TYPED_FOREIGN_CHILD(BaseID,saml2);
             IMPL_TYPED_FOREIGN_CHILD(NameID,saml2);
             IMPL_TYPED_FOREIGN_CHILD(EncryptedID,saml2);
@@ -1602,30 +1508,26 @@ namespace opensaml {
                 m_pos_EncryptedID=m_pos_NameID;
                 ++m_pos_EncryptedID;
             }
+
         public:
-            virtual ~NameIDMappingResponseImpl() { }
+            virtual ~NameIDMappingResponseImpl() {}
     
             NameIDMappingResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
-                : AbstractXMLObject(nsURI, localName, prefix, schemaType)
-            {
+                    : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
                 init();
             }
                 
             NameIDMappingResponseImpl(const NameIDMappingResponseImpl& src) : AbstractXMLObject(src), StatusResponseTypeImpl(src) {
                 init();
+            }
 
-                if (src.getNameID())
-                    setNameID(getNameID()->cloneNameID());
-                if (src.getEncryptedID())
-                    setEncryptedID(getEncryptedID()->cloneEncryptedID());
-
+            void _clone(const NameIDMappingResponseImpl& src) {
+                StatusResponseTypeImpl::_clone(src);
+                IMPL_CLONE_TYPED_CHILD(NameID);
+                IMPL_CLONE_TYPED_CHILD(EncryptedID);
             }
             
-            IMPL_XMLOBJECT_CLONE(NameIDMappingResponse);
-            StatusResponseType* cloneStatusResponseType() const {
-                return cloneNameIDMappingResponse();
-            }
-
+            IMPL_XMLOBJECT_CLONE_EX(NameIDMappingResponse);
             IMPL_TYPED_FOREIGN_CHILD(NameID,saml2);
             IMPL_TYPED_FOREIGN_CHILD(EncryptedID,saml2);
     
@@ -1677,6 +1579,7 @@ IMPL_XMLOBJECTBUILDER(StatusMessage);
 IMPL_XMLOBJECTBUILDER(Terminate);
 
 IMPL_XMLOBJECTBUILDER(RespondTo);
+IMPL_XMLOBJECTBUILDER(Asynchronous);
 
 // Unicode literals
 const XMLCh Artifact::LOCAL_NAME[] = UNICODE_LITERAL_8(A,r,t,i,f,a,c,t);
@@ -1686,6 +1589,8 @@ const XMLCh ArtifactResponse::LOCAL_NAME[] = UNICODE_LITERAL_16(A,r,t,i,f,a,c,t,
 const XMLCh ArtifactResponse::TYPE_NAME[] = UNICODE_LITERAL_20(A,r,t,i,f,a,c,t,R,e,s,p,o,n,s,e,T,y,p,e);
 const XMLCh AssertionIDRequest::LOCAL_NAME[] = UNICODE_LITERAL_18(A,s,s,e,r,t,i,o,n,I,D,R,e,q,u,e,s,t);
 const XMLCh AssertionIDRequest::TYPE_NAME[] = UNICODE_LITERAL_22(A,s,s,e,r,t,i,o,n,I,D,R,e,q,u,e,s,t,T,y,p,e);
+const XMLCh Asynchronous::LOCAL_NAME[] = UNICODE_LITERAL_12(A,s,y,n,c,h,r,o,n,o,u,s);
+const XMLCh Asynchronous::TYPE_NAME[] = UNICODE_LITERAL_16(A,s,y,n,c,h,r,o,n,o,u,s,T,y,p,e);
 const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
 const XMLCh AttributeQuery::TYPE_NAME[] = UNICODE_LITERAL_18(A,t,t,r,i,b,u,t,e,Q,u,e,r,y,T,y,p,e);
 const XMLCh AuthnQuery::LOCAL_NAME[] = UNICODE_LITERAL_10(A,u,t,h,n,Q,u,e,r,y);