[cpp-sp] branch main updated: Major handler refactor to remove Xerces.

Scott Cantor cantor.2 at osu.edu
Wed Jan 8 20:36:31 UTC 2025


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository cpp-sp.

View the commit online:
http://git.shibboleth.net/view/?p=cpp-sp.git;a=commit;h=a43814935030930c49b7a08f5515b861906525c7

The following commit(s) were added to refs/heads/main by this push:
     new a4381493 Major handler refactor to remove Xerces.
a4381493 is described below

commit a43814935030930c49b7a08f5515b861906525c7
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Wed Jan 8 15:36:21 2025 -0500

    Major handler refactor to remove Xerces.
---
 apache/mod_shib_24.cpp                           |   4 +-
 shibsp/Agent.h                                   |   2 +-
 shibsp/AgentConfig.h                             |   6 +
 shibsp/Makefile.am                               |   9 -
 shibsp/RequestMapper.h                           |   5 +-
 shibsp/base.h                                    |  24 +-
 shibsp/handler/AbstractHandler.h                 | 147 +++---
 shibsp/handler/AssertionConsumerService.h        |  20 +-
 shibsp/handler/Handler.h                         |  47 --
 shibsp/handler/LogoutHandler.h                   |  37 +-
 shibsp/handler/LogoutInitiator.h                 |  24 +-
 shibsp/handler/RemotedHandler.h                  |  24 +-
 shibsp/handler/SecuredHandler.h                  |  32 +-
 shibsp/handler/SessionInitiator.h                |  39 +-
 shibsp/handler/impl/AbstractHandler.cpp          | 337 ++++--------
 shibsp/handler/impl/AdminLogoutInitiator.cpp     | 133 +----
 shibsp/handler/impl/AssertionConsumerService.cpp |  97 +---
 shibsp/handler/impl/AssertionLookup.cpp          | 190 -------
 shibsp/handler/impl/AttributeCheckerHandler.cpp  | 130 ++---
 shibsp/handler/impl/DiscoveryFeed.cpp            | 329 ------------
 shibsp/handler/impl/LocalLogoutInitiator.cpp     | 124 +----
 shibsp/handler/impl/LogoutHandler.cpp            |  35 +-
 shibsp/handler/impl/LogoutInitiator.cpp          |  24 +-
 shibsp/handler/impl/MetadataGenerator.cpp        | 628 +----------------------
 shibsp/handler/impl/RemotedHandler.cpp           |   2 +-
 shibsp/handler/impl/SAML2Consumer.cpp            |  26 +-
 shibsp/handler/impl/SAML2Logout.cpp              |  26 +-
 shibsp/handler/impl/SAML2LogoutInitiator.cpp     |  26 +-
 shibsp/handler/impl/SAML2SessionInitiator.cpp    |  26 +-
 shibsp/handler/impl/SAMLDSSessionInitiator.cpp   |   2 +-
 shibsp/handler/impl/SecuredHandler.cpp           |  55 +-
 shibsp/handler/impl/SessionHandler.cpp           |  54 +-
 shibsp/handler/impl/SessionInitiator.cpp         |  68 +--
 shibsp/handler/impl/StatusHandler.cpp            | 297 ++---------
 shibsp/impl/AgentConfig.cpp                      |  19 +-
 shibsp/paths.h.in                                |  24 +-
 shibsp/resource.h                                |  24 +-
 shibsp/util/BoostPropertySet.cpp                 |  12 +-
 shibsp/util/BoostPropertySet.h                   |   8 +-
 shibsp/util/CGIParser.cpp                        |  26 +-
 shibsp/util/CGIParser.h                          |  24 +-
 shibsp/util/DOMPropertySet.cpp                   | 257 ----------
 shibsp/util/DOMPropertySet.h                     | 154 ------
 shibsp/util/IPRange.cpp                          |  24 +-
 shibsp/util/IPRange.h                            |  24 +-
 shibsp/util/PathResolver.cpp                     |  26 +-
 shibsp/util/PropertySet.h                        |  78 ---
 shibsp/util/SPConstants.cpp                      | 110 +---
 shibsp/util/SPConstants.h                        |  46 +-
 shibsp/version.cpp                               |  24 +-
 shibsp/version.h                                 |  63 ++-
 tests/util/BoostPropertySetTests.cpp             |   2 +-
 52 files changed, 687 insertions(+), 3287 deletions(-)

diff --git a/apache/mod_shib_24.cpp b/apache/mod_shib_24.cpp
index ee79310f..cf050ed3 100644
--- a/apache/mod_shib_24.cpp
+++ b/apache/mod_shib_24.cpp
@@ -1016,7 +1016,7 @@ AccessControl::aclresult_t htAccessControl::authorized(const SPRequest& request,
     throw ConfigurationException("Save my walrus!");
 }
 
-class ApacheRequestMapper : public virtual RequestMapper, public virtual PropertySet2
+class ApacheRequestMapper : public virtual RequestMapper, public virtual PropertySet
 {
 public:
     ApacheRequestMapper(ptree& pt, bool deprecationSupport=true);
@@ -1037,7 +1037,7 @@ public:
 private:
     unique_ptr<RequestMapper> m_mapper;
     static thread_local const ShibTargetApache* m_sta;
-    static thread_local const PropertySet2* m_props;
+    static thread_local const PropertySet* m_props;
     mutable htAccessControl m_htaccess;
 };
 
diff --git a/shibsp/Agent.h b/shibsp/Agent.h
index abc06193..bc202b5d 100644
--- a/shibsp/Agent.h
+++ b/shibsp/Agent.h
@@ -47,7 +47,7 @@ namespace shibsp {
      * <p>A ServiceProvider exposes configuration and infrastructure services required
      * by the SP implementation, allowing a flexible configuration format.
      */
-	class SHIBSP_API Agent : public virtual PropertySet2
+	class SHIBSP_API Agent : public virtual PropertySet
     {
         MAKE_NONCOPYABLE(Agent);
     protected:
diff --git a/shibsp/AgentConfig.h b/shibsp/AgentConfig.h
index 1dd22de3..ca0fa675 100644
--- a/shibsp/AgentConfig.h
+++ b/shibsp/AgentConfig.h
@@ -31,6 +31,7 @@ namespace shibsp {
     class SHIBSP_API AccessControl;
     class SHIBSP_API Agent;
     class SHIBSP_API Category;
+    class SHIBSP_API Handler;
     class SHIBSP_API LoggingService;
     class SHIBSP_API PathResolver;
     class SHIBSP_API RemotingService;
@@ -90,6 +91,11 @@ namespace shibsp {
          */
         PluginManager<Agent,std::string,boost::property_tree::ptree&> AgentManager;
 
+        /**
+         * Manages factories for Handler plugins.
+         */
+        PluginManager<Handler,std::string,std::pair<boost::property_tree::ptree&,const char*>> HandlerManager;
+
         /**
          * Manages factories for LoggingService plugins.
          */
diff --git a/shibsp/Makefile.am b/shibsp/Makefile.am
index 90934234..3c46a039 100644
--- a/shibsp/Makefile.am
+++ b/shibsp/Makefile.am
@@ -71,7 +71,6 @@ utilinclude_HEADERS = \
 	util/BoostPropertySet.h \
 	util/CGIParser.h \
 	util/Date.h \
-	util/DOMPropertySet.h \
 	util/IPRange.h \
 	util/Lockable.h \
 	util/PathResolver.h \
@@ -100,19 +99,12 @@ libshibsp_la_SOURCES = \
 	handler/impl/AbstractHandler.cpp \
 	handler/impl/AdminLogoutInitiator.cpp \
 	handler/impl/AssertionConsumerService.cpp \
-	handler/impl/AssertionLookup.cpp \
 	handler/impl/AttributeCheckerHandler.cpp \
-	handler/impl/DiscoveryFeed.cpp \
 	handler/impl/LocalLogoutInitiator.cpp \
 	handler/impl/LogoutHandler.cpp \
 	handler/impl/LogoutInitiator.cpp \
 	handler/impl/MetadataGenerator.cpp \
 	handler/impl/RemotedHandler.cpp \
-	handler/impl/SAML2Consumer.cpp \
-	handler/impl/SAML2Logout.cpp \
-	handler/impl/SAML2LogoutInitiator.cpp \
-	handler/impl/SAML2SessionInitiator.cpp \
-	handler/impl/SAMLDSSessionInitiator.cpp \
 	handler/impl/SecuredHandler.cpp \
 	handler/impl/SessionHandler.cpp \
 	handler/impl/SessionInitiator.cpp \
@@ -135,7 +127,6 @@ libshibsp_la_SOURCES = \
 	session/impl/AbstractSessionCache.cpp \
 	util/BoostPropertySet.cpp \
 	util/CGIParser.cpp \
-	util/DOMPropertySet.cpp \
 	util/IPRange.cpp \
 	util/PathResolver.cpp \
 	util/ReloadableXMLFile.cpp \
diff --git a/shibsp/RequestMapper.h b/shibsp/RequestMapper.h
index d8c945d8..6ffef204 100644
--- a/shibsp/RequestMapper.h
+++ b/shibsp/RequestMapper.h
@@ -27,14 +27,13 @@
 #ifndef __shibsp_reqmap_h__
 #define __shibsp_reqmap_h__
 
-#include <shibsp/base.h>
 #include <shibsp/util/Lockable.h>
 
 namespace shibsp {
 
     class SHIBSP_API AccessControl;
     class SHIBSP_API HTTPRequest;
-    class SHIBSP_API PropertySet2;
+    class SHIBSP_API PropertySet;
 
     /**
      * Interface to a request mapping plugin
@@ -51,7 +50,7 @@ namespace shibsp {
         virtual ~RequestMapper();
 
         /** Combination of configuration settings and effective access control. */
-        typedef std::pair<const PropertySet2*,AccessControl*> Settings;
+        typedef std::pair<const PropertySet*,AccessControl*> Settings;
 
         /**
          * Map request to settings.
diff --git a/shibsp/base.h b/shibsp/base.h
index afece18d..ea03749c 100644
--- a/shibsp/base.h
+++ b/shibsp/base.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/handler/AbstractHandler.h b/shibsp/handler/AbstractHandler.h
index 113dd752..73c193f1 100644
--- a/shibsp/handler/AbstractHandler.h
+++ b/shibsp/handler/AbstractHandler.h
@@ -15,107 +15,80 @@
 /**
  * @file shibsp/handler/AbstractHandler.h
  * 
- * Base class for handlers based on a DOMPropertySet. 
+ * Base class for handlers based on a DOMPropertySet.
  */
 
 #ifndef __shibsp_abshandler_h__
 #define __shibsp_abshandler_h__
 
 #include <shibsp/handler/Handler.h>
-#include <shibsp/logging/Category.h>
 #include <shibsp/remoting/ddf.h>
-#include <shibsp/util/DOMPropertySet.h>
+#include <shibsp/util/BoostPropertySet.h>
 
-#include <map>
 #include <string>
-
-
-namespace xmltooling {
-    class XMLTOOL_API XMLObject;
-};
+#include <boost/property_tree/ptree_fwd.hpp>
 
 namespace shibsp {
 
+    class SHIBSP_API Category;
+    class SHIBSP_API SPRequest;
+
 #if defined (_MSC_VER)
     #pragma warning( push )
     #pragma warning( disable : 4250 )
 #endif
 
     /**
-     * Base class for handlers based on a DOMPropertySet.
+     * Base class for handlers based on a BoostPropertySet.
+     * 
+     * TODO: Most of this probably is replaced/removed with hub operations.
      */
-    class SHIBSP_API AbstractHandler : public virtual Handler, public DOMPropertySet
+    class SHIBSP_API AbstractHandler : public virtual Handler, public virtual BoostPropertySet
     {
     protected:
         /**
          * Constructor
          * 
-         * @param e         DOM element to load as property set.
-         * @param log       logging category to use
-         * @param filter    optional filter controls what child elements to include as nested PropertySets
-         * @param remapper  optional property rename mapper for legacy property support
+         * @param pt    root of handler configuration
+         * @param log   logging category to use
          */
-        AbstractHandler(
-            const xercesc::DOMElement* e,
-            Category& log,
-            xercesc::DOMNodeFilter* filter=nullptr,
-            const Remapper* remapper=nullptr
-            );
-
-        void log(Priority::Value level, const std::string& msg) const;
+        AbstractHandler(const boost::property_tree::ptree& pt, Category& log);
 
-#ifndef SHIBSP_LITE
         /**
-         * Examines a protocol response message for errors and raises an annotated exception
-         * if an error is found.
-         * 
-         * <p>The base class version understands SAML 1.x and SAML 2.0 responses.
-         * 
-         * @param response  a response message of some known protocol
-         * @param role      issuer of message
+         * Prevents unused relay state from building up by cleaning old state from the client.
+         *
+         * <p>Handlers that generate relay state should call this method as a house cleaning
+         * step.
+         *
+         * @param application   the associated Application
+         * @param request       SP request
          */
-        virtual void checkError(
-            const xmltooling::XMLObject* response,
-            const opensaml::saml2md::RoleDescriptor* role=nullptr
-            ) const;
+        virtual void cleanRelayState(SPRequest& request) const;
 
         /**
-         * Prepares Status information in a SAML 2.0 response.
-         * 
-         * @param response  SAML 2.0 response message
-         * @param code      SAML status code
-         * @param subcode   optional SAML substatus code
-         * @param msg       optional message to pass back
+         * Implements various mechanisms to preserve RelayState,
+         * such as cookies or StorageService-backed keys.
+         *
+         * <p>If a supported mechanism can be identified, the input parameter will be
+         * replaced with a suitable state key.
+         *
+         * @param response      outgoing HTTP response
+         * @param relayState    RelayState token to supply with message
          */
-        void fillStatus(
-            opensaml::saml2p::StatusResponseType& response, const XMLCh* code, const XMLCh* subcode=nullptr, const char* msg=nullptr
-            ) const;
+        virtual void preserveRelayState(SPRequest& response, std::string& relayState) const;
 
         /**
-        * Encodes and sends SAML 2.0 message, optionally signing it in the process.
-        * If the method returns, the message MUST NOT be freed by the caller.
-        *
-        * @param encoder                the MessageEncoder to use
-        * @param msg                    the message to send
-        * @param relayState             any RelayState to include with the message
-        * @param destination            location to send message, if not a backchannel response
-        * @param role                   recipient of message, if known
-        * @param application            the Application sending the message
-        * @param httpResponse           channel for sending message
-        * @param defaultSigningProperty the effective value of the "signing" property if unset
-        * @return  the result of sending the message using the encoder
-        */
-        long sendMessage(
-            const opensaml::MessageEncoder& encoder,
-            xmltooling::XMLObject* msg,
-            const char* relayState,
-            const char* destination,
-            const opensaml::saml2md::RoleDescriptor* role,
-            const Application& application,
-            xmltooling::HTTPResponse& httpResponse,
-            const char* defaultSigningProperty
-        ) const;
-#endif
+         * Implements various mechanisms to recover RelayState,
+         * such as cookies or StorageService-backed keys.
+         *
+         * <p>If a supported mechanism can be identified, the input parameter will be
+         * replaced with the recovered state information.
+         *
+         * @param request       SP request
+         * @param relayState    RelayState token supplied with message
+         * @param clear         true iff the token state should be cleared
+         */
+        virtual void recoverRelayState(SPRequest& request, std::string& relayState, bool clear=true) const;
 
         /**
          * Implements a mechanism to preserve form post data.
@@ -148,7 +121,7 @@ namespace shibsp {
         virtual long sendPostResponse(HTTPResponse& response, const char* url, DDF& postData) const;
 
         /**
-         * Bitmask of property sources to read from
+         * Bitmask of property sources to read from:
          * (request query parameter, request mapper, fixed handler property).
          */
         enum PropertySourceTypes {
@@ -158,21 +131,22 @@ namespace shibsp {
             HANDLER_PROPERTY_ALL = 255
         };
 
-        using DOMPropertySet::getBool;
-        using DOMPropertySet::getString;
-        using DOMPropertySet::getUnsignedInt;
-        using DOMPropertySet::getInt;
+        using BoostPropertySet::getBool;
+        using BoostPropertySet::getString;
+        using BoostPropertySet::getUnsignedInt;
+        using BoostPropertySet::getInt;
 
         /**
          * Returns a boolean-valued property.
          * 
          * @param name          property name
          * @param request       reference to incoming request
+         * @param defaultValue  value to return if property is not set
          * @param type          bitmask of property sources to use
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
+         * @return property value (or the default)
          */
-        std::pair<bool,bool> getBool(
-            const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL
+        bool getBool(
+            const char* name, const SPRequest& request, bool defaultValue, unsigned int type=HANDLER_PROPERTY_ALL
             ) const;
 
         /**
@@ -180,30 +154,39 @@ namespace shibsp {
          * 
          * @param name          property name
          * @param request       reference to incoming request
+         * @param defaultValue  value to return if property is not set
          * @param type          bitmask of property sources to use
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
+         * @return property value (or the default)
          */
-        std::pair<bool,const char*> getString(const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
+        const char* getString(
+            const char* name, const SPRequest& request, const char* defaultValue=nullptr, unsigned int type=HANDLER_PROPERTY_ALL
+            ) const;
 
         /**
          * Returns an unsigned integer-valued property.
          * 
          * @param name          property name
          * @param request       reference to incoming request
+         * @param defaultValue  value to return if property is not set
          * @param type          bitmask of property sources to use
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
+         * @return property value (or the default)
          */
-        std::pair<bool,unsigned int> getUnsignedInt(const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
+        unsigned int getUnsignedInt(
+            const char* name, const SPRequest& request, unsigned int defaultValue, unsigned int type=HANDLER_PROPERTY_ALL
+            ) const;
 
         /**
          * Returns an integer-valued property.
          * 
          * @param name          property name
          * @param request       reference to incoming request
+         * @param defaultValue  value to return if property is not set
          * @param type          bitmask of property sources to use
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
+         * @return property value (or the default)
          */
-        std::pair<bool,int> getInt(const char* name, const HTTPRequest& request, unsigned int type=HANDLER_PROPERTY_ALL) const;
+        int getInt(
+            const char* name, const SPRequest& request, int defaultValue, unsigned int type=HANDLER_PROPERTY_ALL
+            ) const;
 
         /** Logging object. */
         Category& m_log;
diff --git a/shibsp/handler/AssertionConsumerService.h b/shibsp/handler/AssertionConsumerService.h
index e52759ef..b26b5ad1 100644
--- a/shibsp/handler/AssertionConsumerService.h
+++ b/shibsp/handler/AssertionConsumerService.h
@@ -44,33 +44,21 @@ namespace shibsp {
     /**
      * Base class for handlers that create sessions by consuming SSO protocol responses.
      */
-    class SHIBSP_API AssertionConsumerService : public AbstractHandler, public RemotedHandler 
+    class SHIBSP_API AssertionConsumerService : public AbstractHandler
     {
     public:
         virtual ~AssertionConsumerService();
 
         std::pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-        void receive(DDF& in, std::ostream& out);
 
     protected:
         /**
          * Constructor
          * 
          * @param e         root of DOM configuration
-         * @param appId     ID of application that "owns" the handler
          * @param log       a logging object to use
-         * @param filter    optional filter controls what child elements to include as nested PropertySets
-         * @param remapper  optional property rename mapper for legacy property support
-         * @param deprecationSupport true iff deprecated settings and features should be supported
          */
-        AssertionConsumerService(
-            const xercesc::DOMElement* e,
-            const char* appId,
-            Category& log,
-            xercesc::DOMNodeFilter* filter=nullptr,
-            const Remapper* remapper=nullptr,
-            bool deprecationSupport=true
-            );
+        AssertionConsumerService(const boost::property_tree::ptree& pt, Category& log);
 
         /**
          * Enforce address checking requirements.
@@ -161,9 +149,7 @@ namespace shibsp {
             const std::vector<const opensaml::Assertion*>* tokens=nullptr
             ) const;
 #endif
-    private:
-        std::pair<bool,long> processMessage(const SPRequest& request) const;
-        
+    private:        
         std::pair<bool,long> sendRedirect(
             SPRequest& request,
             const char* entityID,
diff --git a/shibsp/handler/Handler.h b/shibsp/handler/Handler.h
index 1e832770..e8d6dc7b 100644
--- a/shibsp/handler/Handler.h
+++ b/shibsp/handler/Handler.h
@@ -39,50 +39,6 @@ namespace shibsp {
     protected:
         Handler();
 
-        /**
-         * Log using handler's specific logging object.
-         *
-         * @param level logging level
-         * @param msg   message to log
-         */
-        virtual void log(Priority::Value level, const std::string& msg) const;
-
-        /**
-         * Prevents unused relay state from building up by cleaning old state from the client.
-         *
-         * <p>Handlers that generate relay state should call this method as a house cleaning
-         * step.
-         *
-         * @param application   the associated Application
-         * @param request       SP request
-         */
-        virtual void cleanRelayState(SPRequest& request) const;
-
-        /**
-         * Implements various mechanisms to preserve RelayState,
-         * such as cookies or StorageService-backed keys.
-         *
-         * <p>If a supported mechanism can be identified, the input parameter will be
-         * replaced with a suitable state key.
-         *
-         * @param response      outgoing HTTP response
-         * @param relayState    RelayState token to supply with message
-         */
-        virtual void preserveRelayState(SPRequest& response, std::string& relayState) const;
-
-        /**
-         * Implements various mechanisms to recover RelayState,
-         * such as cookies or StorageService-backed keys.
-         *
-         * <p>If a supported mechanism can be identified, the input parameter will be
-         * replaced with the recovered state information.
-         *
-         * @param request       SP request
-         * @param relayState    RelayState token supplied with message
-         * @param clear         true iff the token state should be cleared
-         */
-        virtual void recoverRelayState(SPRequest& request, std::string& relayState, bool clear=true) const;
-
     public:
         virtual ~Handler();
 
@@ -127,9 +83,6 @@ namespace shibsp {
     /** Handler for hooking new sessions with attribute checking. */
     #define ATTR_CHECKER_HANDLER "AttributeChecker"
 
-    /** Handler for metadata generation. */
-    #define DISCOVERY_FEED_HANDLER "DiscoveryFeed"
-
     /** Handler for metadata generation. */
     #define METADATA_GENERATOR_HANDLER "MetadataGenerator"
 
diff --git a/shibsp/handler/LogoutHandler.h b/shibsp/handler/LogoutHandler.h
index 892f9e0d..67a3f8dc 100644
--- a/shibsp/handler/LogoutHandler.h
+++ b/shibsp/handler/LogoutHandler.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
@@ -39,7 +33,7 @@ namespace shibsp {
     /**
      * Base class for logout-related handlers.
      */
-    class SHIBSP_API LogoutHandler : public RemotedHandler
+    class SHIBSP_API LogoutHandler
     {
     public:
         virtual ~LogoutHandler();
@@ -60,17 +54,6 @@ namespace shibsp {
          */
         std::pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
 
-        /**
-         * A remoted procedure that will perform any necessary back-channel
-         * notifications. The input structure must contain an "application_id" member,
-         * and a "sessions" list containing the session keys, along with an integer
-         * member called "notify" with a value of 1.
-         * 
-         * @param in    incoming DDF message
-         * @param out   stream to write outgoing DDF message to
-         */
-        void receive(DDF& in, std::ostream& out);
-
     protected:
         LogoutHandler();
         
diff --git a/shibsp/handler/LogoutInitiator.h b/shibsp/handler/LogoutInitiator.h
index bb2532a7..e0b11102 100644
--- a/shibsp/handler/LogoutInitiator.h
+++ b/shibsp/handler/LogoutInitiator.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/handler/RemotedHandler.h b/shibsp/handler/RemotedHandler.h
index 36f77c1c..b5637cd6 100644
--- a/shibsp/handler/RemotedHandler.h
+++ b/shibsp/handler/RemotedHandler.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/handler/SecuredHandler.h b/shibsp/handler/SecuredHandler.h
index cdec02d4..22c765ee 100644
--- a/shibsp/handler/SecuredHandler.h
+++ b/shibsp/handler/SecuredHandler.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
@@ -52,16 +46,12 @@ namespace shibsp {
          * @param log           logging category to use
          * @param aclProperty   name of IP/CIDR ACL property
          * @param defaultACL    IP/CIDR ACL to apply if no acl property is set
-         * @param filter        optional filter controls what child elements to include as nested PropertySets
-         * @param remapper      optional property rename mapper for legacy property support
          */
         SecuredHandler(
-            const xercesc::DOMElement* e,
+            const boost::property_tree::ptree& pt,
             Category& log,
             const char* aclProperty="acl",
-            const char* defaultACL=nullptr,
-            xercesc::DOMNodeFilter* filter=nullptr,
-            const Remapper* remapper=nullptr
+            const char* defaultACL=nullptr
             );
 
     public:
diff --git a/shibsp/handler/SessionInitiator.h b/shibsp/handler/SessionInitiator.h
index 3a134209..1c4ea124 100644
--- a/shibsp/handler/SessionInitiator.h
+++ b/shibsp/handler/SessionInitiator.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
@@ -27,8 +21,7 @@
 #ifndef __shibsp_sesinitiator_h__
 #define __shibsp_sesinitiator_h__
 
-#include <shibsp/handler/Handler.h>
-#include <shibsp/util/DOMPropertySet.h>
+#include <shibsp/handler/AbstractHandler.h>
 
 #include <set>
 #include <string>
@@ -46,7 +39,7 @@ namespace shibsp {
      * <p>By default, SessionInitiators look for an entityID on the incoming request
      * and pass control to the specialized run method.
      */
-    class SHIBSP_API SessionInitiator : public virtual Handler, public DOMPropertySet::Remapper
+    class SHIBSP_API SessionInitiator : public virtual AbstractHandler
     {
         friend void SHIBSP_API registerSessionInitiators();
     protected:
@@ -54,7 +47,13 @@ namespace shibsp {
         /** Set of optional settings supported by handler. */
         std::set<std::string> m_supportedOptions;
 
-        SessionInitiator();
+        /**
+         * Constructor.
+         * 
+         * @param pt    root of handler configuration
+         * @param log   logging category
+         */
+        SessionInitiator(const boost::property_tree::ptree& pt, Category& log);
 
         /**
          * Examines the request and applicable settings to determine whether
@@ -92,8 +91,6 @@ namespace shibsp {
         virtual std::pair<bool,long> run(SPRequest& request, std::string& entityID, bool isHandler=true) const=0;
 
         std::pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-
-        const char* remap(const char* src, Category& log) const;
     };
     
 };
diff --git a/shibsp/handler/impl/AbstractHandler.cpp b/shibsp/handler/impl/AbstractHandler.cpp
index ce5e9639..fd0013fd 100644
--- a/shibsp/handler/impl/AbstractHandler.cpp
+++ b/shibsp/handler/impl/AbstractHandler.cpp
@@ -15,7 +15,7 @@
 /**
  * handler/impl/AbstractHandler.cpp
  *
- * Base class for handlers based on a DOMPropertySet.
+ * Base class for handlers based on a BoostPropertySet.
  */
 
 #include "internal.h"
@@ -26,22 +26,21 @@
 #include "SPRequest.h"
 #include "handler/AbstractHandler.h"
 #include "handler/LogoutHandler.h"
+#include "logging/Category.h"
 #include "remoting/RemotingService.h"
 #include "util/CGIParser.h"
+#include "util/Misc.h"
 #include "util/SPConstants.h"
 #include "util/PathResolver.h"
 #include "util/URLEncoder.h"
 
 #include <vector>
 #include <fstream>
-#define BOOST_BIND_GLOBAL_PLACEHOLDERS
-#include <boost/bind.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/algorithm/string.hpp>
 
 using namespace shibsp;
-using namespace xercesc;
-using namespace boost;
+using namespace boost::property_tree;
 using namespace std;
 
 #ifndef HAVE_STRCASECMP
@@ -49,21 +48,19 @@ using namespace std;
 #endif
 
 namespace shibsp {
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2ConsumerFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2LogoutFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory AssertionLookupFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory AttributeCheckerFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory DiscoveryFeedFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory MetadataGeneratorFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory StatusHandlerFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SessionHandlerFactory;
-
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory AdminLogoutInitiatorFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2LogoutInitiatorFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory LocalLogoutInitiatorFactory;
-
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAML2SessionInitiatorFactory;
-    SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<const DOMElement*,const char*> >::Factory SAMLDSSessionInitiatorFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SAML2ConsumerFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SAML2LogoutFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory AttributeCheckerFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory MetadataGeneratorFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory StatusHandlerFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SessionHandlerFactory;
+
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory AdminLogoutInitiatorFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SAML2LogoutInitiatorFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory LocalLogoutInitiatorFactory;
+
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SAML2SessionInitiatorFactory;
+    extern SHIBSP_DLLLOCAL PluginManager< Handler,string,pair<ptree&,const char*> >::Factory SAMLDSSessionInitiatorFactory;
 
     void SHIBSP_DLLLOCAL generateRandomHex(std::string& buf, unsigned int len) {
         static char DIGITS[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
@@ -86,13 +83,13 @@ void SHIBSP_API shibsp::registerHandlers()
 {
     AgentConfig& conf=AgentConfig::getConfig();
 
-    //conf.AssertionConsumerServiceManager.registerFactory(SAML20_ASSERTION_CONSUMER_SERVICE, SAML2ConsumerFactory);
+    conf.HandlerManager.registerFactory(ATTR_CHECKER_HANDLER, AttributeCheckerFactory);
+    conf.HandlerManager.registerFactory(METADATA_GENERATOR_HANDLER, MetadataGeneratorFactory);
+    conf.HandlerManager.registerFactory(SESSION_HANDLER, SessionHandlerFactory);
+
+    //conf.HandlerManager.registerFactory(SAML20_ASSERTION_CONSUMER_SERVICE, SAML2ConsumerFactory);
  
-    //conf.HandlerManager.registerFactory(ATTR_CHECKER_HANDLER, AttributeCheckerFactory);
-    //conf.HandlerManager.registerFactory(DISCOVERY_FEED_HANDLER, DiscoveryFeedFactory);
-    //conf.HandlerManager.registerFactory(METADATA_GENERATOR_HANDLER, MetadataGeneratorFactory);
     //conf.HandlerManager.registerFactory(STATUS_HANDLER, StatusHandlerFactory);
-    //conf.HandlerManager.registerFactory(SESSION_HANDLER, SessionHandlerFactory);
 
     //conf.HandlerManager.registerFactory(SAML20_LOGOUT_HANDLER, SAML2LogoutFactory);
 
@@ -100,8 +97,8 @@ void SHIBSP_API shibsp::registerHandlers()
     //conf.HandlerManager.registerFactory(SAML2_LOGOUT_INITIATOR, SAML2LogoutInitiatorFactory);
     //conf.HandlerManager.registerFactory(LOCAL_LOGOUT_INITIATOR, LocalLogoutInitiatorFactory);
 
-    //conf.SessionInitiatorManager.registerFactory(SAML2_SESSION_INITIATOR, SAML2SessionInitiatorFactory);
-    //conf.SessionInitiatorManager.registerFactory(SAMLDS_SESSION_INITIATOR, SAMLDSSessionInitiatorFactory);
+    //conf.HandlerManager.registerFactory(SAML2_SESSION_INITIATOR, SAML2SessionInitiatorFactory);
+    //conf.HandlerManager.registerFactory(SAMLDS_SESSION_INITIATOR, SAMLDSSessionInitiatorFactory);
 } 
 
 Handler::Handler()
@@ -112,17 +109,21 @@ Handler::~Handler()
 {
 }
 
-const char* Handler::getEventType() const
+AbstractHandler::AbstractHandler(const ptree& pt, Category& log) : m_log(log) {
+    load(pt);
+}
+
+AbstractHandler::~AbstractHandler()
 {
-    return nullptr;
 }
 
-void Handler::log(Priority::Value level, const string& msg) const
+
+const char* Handler::getEventType() const
 {
-    Category::getInstance(SHIBSP_LOGCAT ".Handler").log(level, msg);
+    return nullptr;
 }
 
-void Handler::cleanRelayState(SPRequest& request) const
+void AbstractHandler::cleanRelayState(SPRequest& request) const
 {
     const char* mech = request.getRequestSettings().first->getString("relayState");
 
@@ -142,7 +143,7 @@ void Handler::cleanRelayState(SPRequest& request) const
     // Walk the list of cookies backwards by name.
     const map<string,string>& cookies = request.getCookies();
     for (map<string,string>::const_reverse_iterator i = cookies.rbegin(); i != cookies.rend(); ++i) {
-        if (starts_with(i->first, "_shibstate_")) {
+        if (boost::starts_with(i->first, "_shibstate_")) {
             if (maxRSCookies > 0) {
                 // Keep it, but count it against the limit.
                 --maxRSCookies;
@@ -153,7 +154,7 @@ void Handler::cleanRelayState(SPRequest& request) const
                 ++purgedRSCookies;
             }
         }
-        else if (starts_with(i->first, "_opensaml_req_")) {
+        else if (boost::starts_with(i->first, "_opensaml_req_")) {
             if (maxOSCookies > 0) {
                 // Keep it, but count it against the limit.
                 --maxOSCookies;
@@ -167,17 +168,17 @@ void Handler::cleanRelayState(SPRequest& request) const
     }
 
     if (purgedRSCookies > 0)
-        log(Priority::SHIB_DEBUG, string("purged ") + lexical_cast<string>(purgedRSCookies) + " stale relay state cookie(s) from client");
+        m_log.debug(string("purged ") + boost::lexical_cast<string>(purgedRSCookies) + " stale relay state cookie(s) from client");
     if (purgedOSCookies > 0)
-        log(Priority::SHIB_DEBUG, string("purged ") + lexical_cast<string>(purgedOSCookies) + " stale request correlation cookie(s) from client");
+        m_log.debug(string("purged ") + boost::lexical_cast<string>(purgedOSCookies) + " stale request correlation cookie(s) from client");
 }
 
-void Handler::preserveRelayState(SPRequest& request, string& relayState) const
+void AbstractHandler::preserveRelayState(SPRequest& request, string& relayState) const
 {
     // The empty string implies no state to deal with but we need to generate a correlation handle.
     if (relayState.empty()) {
         generateRandomHex(relayState, 4);
-        relayState = "corr:" + lexical_cast<string>(time(nullptr)) + '_' + relayState;
+        relayState = "corr:" + boost::lexical_cast<string>(time(nullptr)) + '_' + relayState;
         return;
     }
 
@@ -194,7 +195,7 @@ void Handler::preserveRelayState(SPRequest& request, string& relayState) const
             // Generate a random key for the cookie name instead of the fixed name.
             string rsKey;
             generateRandomHex(rsKey, 4);
-            rsKey = lexical_cast<string>(time(nullptr)) + '_' + rsKey;
+            rsKey = boost::lexical_cast<string>(time(nullptr)) + '_' + rsKey;
             string shib_cookie_name = "_shibstate_" + rsKey;
             request.setCookie(shib_cookie_name.c_str(),
                 AgentConfig::getConfig().getURLEncoder().encode(relayState.c_str()).c_str(),
@@ -252,10 +253,10 @@ void Handler::preserveRelayState(SPRequest& request, string& relayState) const
     }
 }
 
-void Handler::recoverRelayState(SPRequest& request, string& relayState, bool clear) const
+void AbstractHandler::recoverRelayState(SPRequest& request, string& relayState, bool clear) const
 {
     // Sentry value that signifies it was only a correlation tool.
-    if (starts_with(relayState, "corr:")) {
+    if (boost::starts_with(relayState, "corr:")) {
         relayState.clear();
         return;
     }
@@ -306,7 +307,7 @@ void Handler::recoverRelayState(SPRequest& request, string& relayState, bool cle
                     DDFJanitor jin(in),jout(out);
                     out = request.getAgent().getRemotingService()->send(in);
                     if (!out.isstring()) {
-                        log(Priority::SHIB_ERROR, "StorageService-backed RelayState mechanism did not return a state value.");
+                        m_log.error("StorageService-backed RelayState mechanism did not return a state value.");
                         relayState.erase();
                     }
                     else {
@@ -352,166 +353,6 @@ void Handler::recoverRelayState(SPRequest& request, string& relayState, bool cle
     request.absolutize(relayState);
 }
 
-AbstractHandler::AbstractHandler(
-    const DOMElement* e, Category& log, DOMNodeFilter* filter, const Remapper* remapper
-    ) : m_log(log) {
-    load(e, nullptr, filter, remapper);
-}
-
-AbstractHandler::~AbstractHandler()
-{
-}
-
-void AbstractHandler::log(Priority::Value level, const string& msg) const
-{
-    m_log.log(level, msg);
-}
-
-#ifndef SHIBSP_LITE
-
-const char* Handler::getType() const
-{
-    return getString("type").second;
-}
-
-void AbstractHandler::checkError(const XMLObject* response, const saml2md::RoleDescriptor* role) const
-{
-    const saml2p::StatusResponseType* r2 = dynamic_cast<const saml2p::StatusResponseType*>(response);
-    if (r2) {
-        const saml2p::Status* status = r2->getStatus();
-        if (status) {
-            const saml2p::StatusCode* sc = status->getStatusCode();
-            const XMLCh* code = sc ? sc->getValue() : nullptr;
-            if (code && !XMLString::equals(code,saml2p::StatusCode::SUCCESS)) {
-                FatalProfileException ex("SAML response reported an IdP error.");
-                annotateException(&ex, role, status);   // throws it
-            }
-        }
-    }
-
-    const saml1p::Response* r1 = dynamic_cast<const saml1p::Response*>(response);
-    if (r1) {
-        const saml1p::Status* status = r1->getStatus();
-        if (status) {
-            const saml1p::StatusCode* sc = status->getStatusCode();
-            const xmltooling::QName* code = sc ? sc->getValue() : nullptr;
-            if (code && *code != saml1p::StatusCode::SUCCESS) {
-                FatalProfileException ex("SAML response reported an IdP error.");
-                annotateException(&ex, role, status);   // throws it
-            }
-        }
-    }
-}
-
-void AbstractHandler::fillStatus(saml2p::StatusResponseType& response, const XMLCh* code, const XMLCh* subcode, const char* msg) const
-{
-    saml2p::Status* status = saml2p::StatusBuilder::buildStatus();
-    saml2p::StatusCode* scode = saml2p::StatusCodeBuilder::buildStatusCode();
-    status->setStatusCode(scode);
-    scode->setValue(code);
-    if (subcode) {
-        saml2p::StatusCode* ssubcode = saml2p::StatusCodeBuilder::buildStatusCode();
-        scode->setStatusCode(ssubcode);
-        ssubcode->setValue(subcode);
-    }
-    if (msg) {
-        pair<bool,bool> flag = getBool("detailedErrors", shibspconstants::ASCII_SHIBSPCONFIG_NS);
-        auto_ptr_XMLCh widemsg((flag.first && flag.second) ? msg : "Error processing request.");
-        saml2p::StatusMessage* sm = saml2p::StatusMessageBuilder::buildStatusMessage();
-        status->setStatusMessage(sm);
-        sm->setMessage(widemsg.get());
-    }
-    response.setStatus(status);
-}
-
-long AbstractHandler::sendMessage(
-    const MessageEncoder& encoder,
-    XMLObject* msg,
-    const char* relayState,
-    const char* destination,
-    const saml2md::RoleDescriptor* role,
-    const Application& application,
-    HTTPResponse& httpResponse,
-    const char* defaultSigningProperty
-    ) const
-{
-    const EntityDescriptor* entity = role ? dynamic_cast<const EntityDescriptor*>(role->getParent()) : nullptr;
-    const PropertySet* relyingParty = application.getRelyingParty(entity);
-    pair<bool, const char*> flag = getString("signing");
-    if (!flag.first)
-        flag = getString("signing", shibspconstants::ASCII_SHIBSPCONFIG_NS);
-    if (!flag.first)
-        flag = relyingParty->getString("signing");
-    if (SPConfig::shouldSignOrEncrypt(flag.first ? flag.second : defaultSigningProperty, destination, encoder.isUserAgentPresent())) {
-        CredentialResolver* credResolver = application.getCredentialResolver();
-        if (credResolver) {
-            Locker credLocker(credResolver);
-            const Credential* cred = nullptr;
-            pair<bool,const char*> keyName = relyingParty->getString("keyName");
-            pair<bool,const XMLCh*> sigalg = relyingParty->getXMLString("signingAlg");
-            if (role) {
-                MetadataCredentialCriteria mcc(*role);
-                mcc.setUsage(Credential::SIGNING_CREDENTIAL);
-                if (keyName.first)
-                    mcc.getKeyNames().insert(keyName.second);
-                if (sigalg.first) {
-                    // Using an explicit algorithm, so resolve a credential directly.
-                    mcc.setXMLAlgorithm(sigalg.second);
-                    cred = credResolver->resolve(&mcc);
-                }
-                else {
-                    // Prefer credential based on peer's requirements.
-                    pair<const SigningMethod*,const Credential*> p = role->getSigningMethod(*credResolver, mcc);
-                    if (p.first)
-                        sigalg = make_pair(true, p.first->getAlgorithm());
-                    if (p.second)
-                        cred = p.second;
-                }
-            }
-            else {
-                CredentialCriteria cc;
-                cc.setUsage(Credential::SIGNING_CREDENTIAL);
-                if (keyName.first)
-                    cc.getKeyNames().insert(keyName.second);
-                if (sigalg.first)
-                    cc.setXMLAlgorithm(sigalg.second);
-                cred = credResolver->resolve(&cc);
-            }
-            if (cred) {
-                // Signed request.
-                pair<bool,const XMLCh*> digalg = relyingParty->getXMLString("digestAlg");
-                if (!digalg.first && role) {
-                    const DigestMethod* dm = role->getDigestMethod();
-                    if (dm)
-                        digalg = make_pair(true, dm->getAlgorithm());
-                }
-                return encoder.encode(
-                    httpResponse,
-                    msg,
-                    destination,
-                    entity,
-                    relayState,
-                    &application,
-                    cred,
-                    sigalg.second,
-                    (digalg.first ? digalg.second : nullptr)
-                    );
-            }
-            else {
-                m_log.warn("no signing credential resolved, leaving message unsigned");
-            }
-        }
-        else {
-            m_log.warn("no credential resolver installed, leaving message unsigned");
-        }
-    }
-
-    // Unsigned request.
-    return encoder.encode(httpResponse, msg, destination, entity, relayState, &application);
-}
-
-#endif
-
 void AbstractHandler::preservePostData(SPRequest& request, const char* relayState) const
 {
     if (strcasecmp(request.getMethod(), "POST")) {
@@ -579,7 +420,7 @@ void AbstractHandler::preservePostData(SPRequest& request, const char* relayStat
         const map<string,string>& cookies = request.getCookies();
         for (map<string,string>::const_reverse_iterator i = cookies.rbegin(); i != cookies.rend(); ++i) {
             // Process post data cookies only.
-            if (starts_with(i->first, "_shibpost_")) {
+            if (boost::starts_with(i->first, "_shibpost_")) {
                 if (maxCookies > 0) {
                     // Keep it, but count it against the limit.
                     --maxCookies;
@@ -593,7 +434,7 @@ void AbstractHandler::preservePostData(SPRequest& request, const char* relayStat
         }
 
         if (purgedCookies > 0)
-            log(Priority::SHIB_DEBUG, string("purged ") + lexical_cast<string>(purgedCookies) + " stale POST preservation cookie(s) from client");
+            m_log.debug(string("purged ") + boost::lexical_cast<string>(purgedCookies) + " stale POST preservation cookie(s) from client");
 
         // Set a cookie with key info.
         request.setCookie(shib_cookie.c_str(), postkey.c_str(), 0, HTTPResponse::SAMESITE_NONE);
@@ -751,99 +592,111 @@ DDF AbstractHandler::getPostData(const SPRequest& request) const
     return DDF();
 }
 
-pair<bool,bool> AbstractHandler::getBool(const char* name, const HTTPRequest& request, unsigned int type) const
+bool AbstractHandler::getBool(
+    const char* name, const SPRequest& request, bool defaultValue, unsigned int type
+    ) const
 {
     if (type & HANDLER_PROPERTY_REQUEST) {
         const char* param = request.getParameter(name);
-        if (param && *param)
-            return make_pair(true, (*param=='t' || *param=='1'));
+        if (param && *param) {
+            string_to_bool_translator tr;
+            boost::optional<bool> ret = tr.get_value(param);
+            if (ret.has_value()) {
+                return ret.get();
+            }
+        }
     }
     
-    const SPRequest* sprequest = dynamic_cast<const SPRequest*>(&request);
-    if (sprequest && (type & HANDLER_PROPERTY_MAP)) {
-        if (sprequest->getRequestSettings().first->hasProperty(name)) {
+    if (type & HANDLER_PROPERTY_MAP) {
+        if (request.getRequestSettings().first->hasProperty(name)) {
             // The default won't matter since we've already verified the property "exists".
-            return make_pair(true, sprequest->getRequestSettings().first->getBool(name, false));
+            return request.getRequestSettings().first->getBool(name, defaultValue);
         }
     }
 
     if (type & HANDLER_PROPERTY_FIXED) {
-        return getBool(name);
+        return getBool(name, defaultValue);
     }
 
-    return make_pair(false,false);
+    return defaultValue;
 }
 
-pair<bool,const char*> AbstractHandler::getString(const char* name, const HTTPRequest& request, unsigned int type) const
+const char* AbstractHandler::getString(
+    const char* name, const SPRequest& request, const char* defaultValue, unsigned int type
+    ) const
 {
     if (type & HANDLER_PROPERTY_REQUEST) {
         const char* param = request.getParameter(name);
-        if (param && *param)
-            return make_pair(true, param);
+        if (param && *param) {
+            return param;
+        }
     }
     
-    const SPRequest* sprequest = dynamic_cast<const SPRequest*>(&request);
-    if (sprequest && (type & HANDLER_PROPERTY_MAP)) {
-        const char* ret = sprequest->getRequestSettings().first->getString(name);
-        if (ret)
-            return make_pair(true, ret);
+    if (type & HANDLER_PROPERTY_MAP) {
+        if (request.getRequestSettings().first->hasProperty(name)) {
+            // The default won't matter since we've already verified the property "exists".
+            return request.getRequestSettings().first->getString(name, defaultValue);
+        }
     }
 
     if (type & HANDLER_PROPERTY_FIXED) {
-        return getString(name);
+        return getString(name, defaultValue);
     }
 
-    return pair<bool,const char*>(false,nullptr);
+    return defaultValue;
 }
 
-pair<bool,unsigned int> AbstractHandler::getUnsignedInt(const char* name, const HTTPRequest& request, unsigned int type) const
+unsigned int AbstractHandler::getUnsignedInt(
+    const char* name, const SPRequest& request, unsigned int defaultValue, unsigned int type) const
 {
     if (type & HANDLER_PROPERTY_REQUEST) {
         const char* param = request.getParameter(name);
         if (param && *param) {
             try {
-                return pair<bool,unsigned int>(true, lexical_cast<unsigned int>(param));
+                return boost::lexical_cast<unsigned int>(param);
             }
-            catch (bad_lexical_cast&) {
-                return pair<bool,unsigned int>(false,0);
+            catch (const boost::bad_lexical_cast&) {
             }
         }
     }
     
-    const SPRequest* sprequest = dynamic_cast<const SPRequest*>(&request);
-    if (sprequest && (type & HANDLER_PROPERTY_MAP)) {
-        if (sprequest->getRequestSettings().first->hasProperty(name)) {
+    if (type & HANDLER_PROPERTY_MAP) {
+        if (request.getRequestSettings().first->hasProperty(name)) {
             // The default won't matter since we've already verified the property "exists".
-            return make_pair(true, sprequest->getRequestSettings().first->getUnsignedInt(name, 0));
+            return request.getRequestSettings().first->getUnsignedInt(name, defaultValue);
         }
     }
 
     if (type & HANDLER_PROPERTY_FIXED) {
-        return getUnsignedInt(name);
+        return getUnsignedInt(name, defaultValue);
     }
 
-    return pair<bool,unsigned int>(false,0);
+    return defaultValue;
 }
 
-pair<bool,int> AbstractHandler::getInt(const char* name, const HTTPRequest& request, unsigned int type) const
+int AbstractHandler::getInt(const char* name, const SPRequest& request, int defaultValue, unsigned int type) const
 {
     if (type & HANDLER_PROPERTY_REQUEST) {
         const char* param = request.getParameter(name);
-        if (param && *param)
-            return pair<bool,int>(true, atoi(param));
+        if (param && *param) {
+            try {
+                return boost::lexical_cast<unsigned int>(param);
+            }
+            catch (const boost::bad_lexical_cast&) {
+            }
+        }
     }
     
-    const SPRequest* sprequest = dynamic_cast<const SPRequest*>(&request);
-    if (sprequest && (type & HANDLER_PROPERTY_MAP)) {
-        if (sprequest->getRequestSettings().first->hasProperty(name)) {
+    if (type & HANDLER_PROPERTY_MAP) {
+        if (request.getRequestSettings().first->hasProperty(name)) {
             // The default won't matter since we've already verified the property "exists".
-            return make_pair(true, sprequest->getRequestSettings().first->getInt(name, 0));
+            return request.getRequestSettings().first->getInt(name, defaultValue);
         }
     }
 
     if (type & HANDLER_PROPERTY_FIXED) {
-        return getInt(name);
+        return getInt(name, defaultValue);
     }
 
-    return pair<bool,int>(false,0);
+    return defaultValue;
 }
diff --git a/shibsp/handler/impl/AdminLogoutInitiator.cpp b/shibsp/handler/impl/AdminLogoutInitiator.cpp
index 1bbad83a..77d8a9ab 100644
--- a/shibsp/handler/impl/AdminLogoutInitiator.cpp
+++ b/shibsp/handler/impl/AdminLogoutInitiator.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * AdminLogoutInitiator.cpp
+ * handler/impl/AdminLogoutInitiator.cpp
  *
  * Triggers administrative logout of a session.
  */
@@ -30,6 +24,7 @@
 #include "AgentConfig.h"
 #include "handler/SecuredHandler.h"
 #include "handler/LogoutInitiator.h"
+#include "logging/Category.h"
 #include "session/SessionCache.h"
 
 #include <sstream>
@@ -38,9 +33,7 @@
 #endif
 
 using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
-using namespace boost;
+using namespace boost::property_tree;
 using namespace std;
 
 namespace shibsp {
@@ -53,72 +46,27 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL AdminLogoutInitiator : public SecuredHandler, public LogoutInitiator
     {
     public:
-        AdminLogoutInitiator(const DOMElement* e, const char* appId);
+        AdminLogoutInitiator(const ptree& pt);
         virtual ~AdminLogoutInitiator() {}
 
-        void init(const char* location);    // encapsulates actions that need to run either in the c'tor or setParent
-
-        void setParent(const PropertySet* parent);
-        void receive(DDF& in, ostream& out);
         pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-
-    private:
-        pair<bool,long> doRequest(SPRequest& request) const;
-
-        string m_appId;
-#ifndef SHIBSP_LITE
-        auto_ptr_char m_protocol;
-        auto_ptr<LogoutRequest> buildRequest(
-            const Application& application,
-            const Session& session,
-            const RoleDescriptor& role,
-            const XMLCh* endpoint
-            ) const;
-#endif
     };
 
 #if defined (_MSC_VER)
     #pragma warning( pop )
 #endif
 
-    Handler* SHIBSP_DLLLOCAL AdminLogoutInitiatorFactory(const pair<const DOMElement*,const char*>& p, bool)
+    Handler* SHIBSP_DLLLOCAL AdminLogoutInitiatorFactory(const pair<ptree&,const char*> p, bool)
     {
-        return new AdminLogoutInitiator(p.first, p.second);
+        return new AdminLogoutInitiator(p.first);
     }
 };
 
-AdminLogoutInitiator::AdminLogoutInitiator(const DOMElement* e, const char* appId)
-    : SecuredHandler(e, Category::getInstance(SHIBSP_LOGCAT ".LogoutInitiator.Admin")), m_appId(appId)
-#ifndef SHIBSP_LITE
-        ,m_protocol(samlconstants::SAML20P_NS)
-#endif
+AdminLogoutInitiator::AdminLogoutInitiator(const ptree& pt)
+    : SecuredHandler(pt, Category::getInstance(SHIBSP_LOGCAT ".LogoutInitiator.Admin"))
 {
-    // If Location isn't set, defer initialization until the setParent call.
-    pair<bool,const char*> loc = getString("Location");
-    if (loc.first) {
-        init(loc.second);
-    }
 }
 
-void AdminLogoutInitiator::setParent(const PropertySet* parent)
-{
-    DOMPropertySet::setParent(parent);
-    pair<bool,const char*> loc = getString("Location");
-    init(loc.second);
-}
-
-void AdminLogoutInitiator::init(const char* location)
-{
-    if (location) {
-        string address = m_appId + location + "::run::AdminLI";
-        setAddress(address.c_str());
-    }
-    else {
-        m_log.warn("no Location property in Admin LogoutInitiator (or parent), can't register as remoted handler");
-    }
-}
-
-
 pair<bool,long> AdminLogoutInitiator::run(SPRequest& request, bool isHandler) const
 {
     // No front-channel notifications, so skip calling logout base class.
@@ -128,53 +76,6 @@ pair<bool,long> AdminLogoutInitiator::run(SPRequest& request, bool isHandler) co
     if (ret.first)
         return ret;
 
-    if (false) {
-        // When out of process, we run natively.
-        return doRequest(request);
-    }
-    else {
-        // When not out of process, we remote the request.
-        vector<string> headers(1, "User-Agent");
-        DDF out, in = wrap(request, &headers);
-        DDFJanitor jin(in), jout(out);
-        out = send(request, in);
-        return unwrap(request, out);
-    }
-}
-
-void AdminLogoutInitiator::receive(DDF& in, ostream& out)
-{
-#ifndef SHIBSP_LITE
-    // Find application.
-    const char* aid=in["application_id"].string();
-    const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
-    if (!app) {
-        // Something's horribly wrong.
-        m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)");
-        throw ConfigurationException("Unable to locate application for logout, deleted?");
-    }
-
-    // Unpack the request.
-    scoped_ptr<HTTPRequest> req(getRequest(*app, in));
-
-    // Set up a response shim.
-    DDF ret(nullptr);
-    DDFJanitor jout(ret);
-    scoped_ptr<HTTPResponse> resp(getResponse(*app, ret));
-
-    // Since we're remoted, the result should either be a throw, which we pass on,
-    // a false/0 return, which we just return as an empty structure, or a response/redirect,
-    // which we capture in the facade and send back.
-    doRequest(*app, *req, *resp);
-
-    out << ret;
-#else
-    throw ConfigurationException("Cannot perform logout using lite version of shibsp library.");
-#endif
-}
-
-pair<bool,long> AdminLogoutInitiator::doRequest(SPRequest& request) const
-{
     const char* sessionId = request.getParameter("session");
     if (!sessionId || !*sessionId) {
         // Something's horribly wrong.
diff --git a/shibsp/handler/impl/AssertionConsumerService.cpp b/shibsp/handler/impl/AssertionConsumerService.cpp
index 4f32ee3d..d3ad998f 100644
--- a/shibsp/handler/impl/AssertionConsumerService.cpp
+++ b/shibsp/handler/impl/AssertionConsumerService.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * AssertionConsumerService.cpp
+ * handler/impl/AssertionConsumerService.cpp
  *
  * Base class for handlers that create sessions by consuming SSO protocol responses.
  */
@@ -28,33 +22,18 @@
 #include "exceptions.h"
 #include "SPRequest.h"
 #include "handler/AssertionConsumerService.h"
+#include "logging/Category.h"
 #include "util/CGIParser.h"
-#include "util/SPConstants.h"
 
 #include <ctime>
 
-using namespace shibspconstants;
 using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
-using namespace boost;
+using namespace boost::property_tree;
 using namespace std;
 
-AssertionConsumerService::AssertionConsumerService(
-    const DOMElement* e, const char* appId, Category& log, DOMNodeFilter* filter, const Remapper* remapper, bool deprecationSupport
-    ) : AbstractHandler(e, log, filter, remapper)
+AssertionConsumerService::AssertionConsumerService(const ptree& pt, Category& log)
+    : AbstractHandler(pt, log)
 {
-    if (!e)
-        return;
-    string address(appId);
-    address += getString("Location").second;
-    setAddress(address.c_str());
-#ifndef SHIBSP_LITE
-    if (SPConfig::getConfig().isEnabled(SPConfig::OutOfProcess)) {
-        m_decoder.reset(SAMLConfig::getConfig().MessageDecoderManager.newPlugin(getString("Binding").second, e, deprecationSupport));
-        m_decoder->setArtifactResolver(SPConfig::getConfig().getArtifactResolver());
-    }
-#endif
 }
 
 AssertionConsumerService::~AssertionConsumerService()
@@ -77,54 +56,6 @@ pair<bool,long> AssertionConsumerService::run(SPRequest& request, bool isHandler
         }
     }
 
-    if (false) {
-        // When out of process, we run natively and directly process the message.
-        return processMessage(request);
-    }
-    else {
-        // When not out of process, we remote all the message processing.
-        vector<string> headers(1, "Cookie");
-        headers.push_back("User-Agent");
-        headers.push_back("Accept-Language");
-        DDF out,in = wrap(request, &headers);
-        DDFJanitor jin(in), jout(out);
-        out = send(request, in);
-        return unwrap(request, out);
-    }
-}
-
-void AssertionConsumerService::receive(DDF& in, ostream& out)
-{
-    /*
-
-    // Find application.
-    const char* aid = in["application_id"].string();
-    const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
-    if (!app) {
-        // Something's horribly wrong.
-        m_log.error("couldn't find application (%s) for new session", aid ? aid : "(missing)");
-        throw ConfigurationException("Unable to locate application for new session, deleted?");
-    }
-
-    // Unpack the request.
-    scoped_ptr<HTTPRequest> req(getRequest(*app, in));
-
-    // Wrap a response shim.
-    DDF ret(nullptr);
-    DDFJanitor jout(ret);
-    scoped_ptr<HTTPResponse> resp(getResponse(*app, ret));
-
-    // Since we're remoted, the result should either be a throw, a false/0 return,
-    // which we just return as an empty structure, or a response/redirect,
-    // which we capture in the facade and send back.
-    processMessage(*app, *req, *resp);
-    out << ret;
-
-    */
-}
-
-pair<bool,long> AssertionConsumerService::processMessage(const SPRequest& httpRequest) const
-{
 #ifndef SHIBSP_LITE
     // Locate policy key.
     pair<bool,const char*> prop = getString("policyId", shibspconstants::ASCII_SHIBSPCONFIG_NS);  // may be namespace-qualified if inside handler element
diff --git a/shibsp/handler/impl/AssertionLookup.cpp b/shibsp/handler/impl/AssertionLookup.cpp
deleted file mode 100644
index 6346fa68..00000000
--- a/shibsp/handler/impl/AssertionLookup.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/**
- * 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.
- *
- * 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
- *
- * 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.
- */
-
-/**
- * AssertionLookup.cpp
- *
- * Handler for looking up assertions in the SessionCache.
- */
-
-#include "internal.h"
-#include "exceptions.h"
-#include "SPRequest.h"
-#include "handler/RemotedHandler.h"
-#include "handler/SecuredHandler.h"
-#include "session/SessionCache.h"
-#include "util/SPConstants.h"
-
-#include <sstream>
-#include <boost/scoped_ptr.hpp>
-
-using namespace shibspconstants;
-using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
-using namespace boost;
-using namespace std;
-
-namespace shibsp {
-
-#if defined (_MSC_VER)
-    #pragma warning( push )
-    #pragma warning( disable : 4250 )
-#endif
-
-    class SHIBSP_API AssertionLookup : public SecuredHandler, public RemotedHandler
-    {
-    public:
-        AssertionLookup(const DOMElement* e, const char* appId);
-        virtual ~AssertionLookup() {}
-
-        pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-        void receive(DDF& in, ostream& out);
-
-        const char* getType() const {
-            return "AssertionLookup";
-        }
-
-    private:
-        pair<bool,long> processMessage(SPRequest& request) const;
-    };
-
-#if defined (_MSC_VER)
-    #pragma warning( pop )
-#endif
-
-    Handler* SHIBSP_DLLLOCAL AssertionLookupFactory(const pair<const DOMElement*,const char*>& p, bool)
-    {
-        return new AssertionLookup(p.first, p.second);
-    }
-
-};
-
-AssertionLookup::AssertionLookup(const DOMElement* e, const char* appId)
-    : SecuredHandler(e, Category::getInstance(SHIBSP_LOGCAT ".Handler.AssertionLookup"), "exportACL", "127.0.0.1 ::1")
-{
-    pair<bool,const char*> prop = getString("Location");
-    if (!prop.first)
-        throw ConfigurationException("AssertionLookup handler requires Location property.");
-    string address(appId);
-    if (*prop.second != '/')
-        address += '/';
-    address += prop.second;
-    setAddress(address.c_str());
-}
-
-pair<bool,long> AssertionLookup::run(SPRequest& request, bool isHandler) const
-{
-    // Check ACL in base class.
-    pair<bool,long> ret = SecuredHandler::run(request, isHandler);
-    if (ret.first)
-        return ret;
-
-    try {
-        if (false) {
-            // When out of process, we run natively and directly process the message.
-            return processMessage(request);
-        }
-        else {
-            // When not out of process, we remote all the message processing.
-            DDF out,in = wrap(request);
-            DDFJanitor jin(in), jout(out);
-
-            out = send(request, in);
-            return unwrap(request, out);
-        }
-    }
-    catch (std::exception& ex) {
-        m_log.error("error while processing request: %s", ex.what());
-        istringstream msg("Assertion Lookup Failed");
-        return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
-    }
-}
-
-void AssertionLookup::receive(DDF& in, ostream& out)
-{
-    /*
-    // Find application.
-    const char* aid = in["application_id"].string();
-    const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
-    if (!app) {
-        // Something's horribly wrong.
-        m_log.error("couldn't find application (%s) for assertion lookup", aid ? aid : "(missing)");
-        throw ConfigurationException("Unable to locate application for assertion lookup, deleted?");
-    }
-
-    // Unpack the request.
-    scoped_ptr<HTTPRequest> req(getRequest(*app, in));
-    //m_log.debug("found %d client certificates", req->getClientCertificates().size());
-
-    // Wrap a response shim.
-    DDF ret(nullptr);
-    DDFJanitor jout(ret);
-    scoped_ptr<HTTPResponse> resp(getResponse(*app, ret));
-
-    // Since we're remoted, the result should either be a throw, a false/0 return,
-    // which we just return as an empty structure, or a response/redirect,
-    // which we capture in the facade and send back.
-    processMessage(*app, *req, *resp);
-    out << ret;
-    */
-}
-
-pair<bool,long> AssertionLookup::processMessage(SPRequest& request) const
-{
-#ifndef SHIBSP_LITE
-    const char* key = httpRequest.getParameter("key");
-    const char* ID = httpRequest.getParameter("ID");
-    if (!key || !*key || !ID || !*ID) {
-        m_log.error("assertion lookup request failed, missing required parameters");
-        throw FatalProfileException("Missing key or ID parameters.");
-    }
-
-    m_log.debug("processing assertion lookup request (session: %s, assertion: %s)", key, ID);
-
-    SessionCache* cache = application.getServiceProvider().getSessionCache();
-    if (!cache) {
-        m_log.error("session cache does not support extended API");
-        throw FatalProfileException("Session cache does not support assertion lookup.");
-    }
-
-    // The cache will either silently pass a session or nullptr back, or throw an exception out.
-    Session* session = cache->find(application, key);
-    if (!session) {
-        m_log.error("valid session (%s) not found for assertion lookup", key);
-        throw FatalProfileException("Session key not found.");
-    }
-
-    Locker locker(session, false);
-
-    const Assertion* assertion = session->getAssertion(ID);
-    if (!assertion) {
-        m_log.error("assertion (%s) not found in session (%s)", ID, key);
-        throw FatalProfileException("Assertion not found.");
-    }
-
-    stringstream s;
-    s << *assertion;
-    httpResponse.setContentType("application/samlassertion+xml");
-    return make_pair(true, httpResponse.sendResponse(s));
-#else
-    return make_pair(false, 0L);
-#endif
-}
diff --git a/shibsp/handler/impl/AttributeCheckerHandler.cpp b/shibsp/handler/impl/AttributeCheckerHandler.cpp
index 92abcc81..acffbbcb 100644
--- a/shibsp/handler/impl/AttributeCheckerHandler.cpp
+++ b/shibsp/handler/impl/AttributeCheckerHandler.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * AttributeCheckerHandler.cpp
+ * handler/impl/AttributeCheckerHandler.cpp
  *
  * Handler for checking a session for required attributes.
  */
@@ -32,23 +26,15 @@
 #include "SPRequest.h"
 #include "attribute/Attribute.h"
 #include "handler/AbstractHandler.h"
+#include "logging/Category.h"
 #include "session/SessionCache.h"
-#include "util/PathResolver.h"
 
 #include <memory>
 #include <mutex>
-#include <fstream>
-#include <sstream>
-#define BOOST_BIND_GLOBAL_PLACEHOLDERS
-#include <boost/bind.hpp>
 #include <boost/algorithm/string.hpp>
-#include <xercesc/util/XMLUniDefs.hpp>
-#include <xmltooling/util/XMLHelper.h>
 
 using namespace shibsp;
-using namespace xmltooling;
-using namespace boost;
-using namespace xercesc;
+using namespace boost::property_tree;
 using namespace std;
 
 namespace shibsp {
@@ -58,20 +44,10 @@ namespace shibsp {
     #pragma warning( disable : 4250 4251 )
 #endif
 
-    class SHIBSP_DLLLOCAL Blocker : public DOMNodeFilter
-    {
-    public:
-        FilterAction acceptNode(const DOMNode* node) const {
-            return FILTER_REJECT;
-        }
-    };
-
-    static SHIBSP_DLLLOCAL Blocker g_Blocker;
-
     class SHIBSP_API AttributeCheckerHandler : public AbstractHandler
     {
     public:
-        AttributeCheckerHandler(const DOMElement* e, const char* appId, bool deprecationSupport=true);
+        AttributeCheckerHandler(ptree& pt);
         virtual ~AttributeCheckerHandler() {}
 
         pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
@@ -85,7 +61,7 @@ namespace shibsp {
             }
         }
 
-        string m_template;
+        string m_redirectOnFailure;
         bool m_flushSession;
         vector<string> m_attributes;
         unique_ptr<AccessControl> m_acl;
@@ -95,38 +71,34 @@ namespace shibsp {
     #pragma warning( pop )
 #endif
 
-    Handler* SHIBSP_DLLLOCAL AttributeCheckerFactory(const pair<const DOMElement*,const char*>& p, bool deprecationSupport)
+    Handler* SHIBSP_DLLLOCAL AttributeCheckerFactory(const pair<ptree&,const char*>& p, bool deprecationSupport)
     {
-        return new AttributeCheckerHandler(p.first, p.second, deprecationSupport);
+        return new AttributeCheckerHandler(p.first);
     }
-
-    static const XMLCh attributes[] =   UNICODE_LITERAL_10(a,t,t,r,i,b,u,t,e,s);
-    static const XMLCh _flushSession[] = UNICODE_LITERAL_12(f,l,u,s,h,S,e,s,s,i,o,n);
-    static const XMLCh _template[] =    UNICODE_LITERAL_8(t,e,m,p,l,a,t,e);
 };
 
-AttributeCheckerHandler::AttributeCheckerHandler(const DOMElement* e, const char* appId, bool deprecationSupport)
-    : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT ".Handler.AttributeChecker"), &g_Blocker)
+AttributeCheckerHandler::AttributeCheckerHandler(ptree& pt)
+    : AbstractHandler(pt, Category::getInstance(SHIBSP_LOGCAT ".Handler.AttributeChecker"))
 {
-    m_template = XMLHelper::getAttrString(e, nullptr, _template);
-    if (m_template.empty())
-        throw ConfigurationException("AttributeChecker missing required template setting.");
-    AgentConfig::getConfig().getPathResolver().resolve(m_template, PathResolver::SHIBSP_CFG_FILE);
+    m_redirectOnFailure = getString("redirectOnFailure", "");
+    if (m_redirectOnFailure.empty())
+        throw ConfigurationException("AttributeChecker missing required redirectOnFailure setting.");
 
-    m_flushSession = XMLHelper::getAttrBool(e, false, _flushSession);
+    m_flushSession = getBool("flushSession", false);
 
-    string attrs(XMLHelper::getAttrString(e, nullptr, attributes));
+    string attrs(getString("attributes", ""));
     if (!attrs.empty()) {
-        trim(attrs);
-        split(m_attributes, attrs, is_space(), algorithm::token_compress_on);
+        boost::trim(attrs);
+        boost::split(m_attributes, attrs, boost::is_space(), boost::algorithm::token_compress_on);
         if (m_attributes.empty())
             throw ConfigurationException("AttributeChecker unable to parse attributes setting.");
     }
-    else if (nullptr == XMLHelper::getFirstChildElement(e)) {
-        throw ConfigurationException("AttributeChecker requires either the attributes setting or an ACL");
+    else if (hasProperty("path")) {
+        m_log.debug("attempting installation of external AccessControl rule");
+        m_acl.reset(AgentConfig::getConfig().AccessControlManager.newPlugin(XML_ACCESS_CONTROL, pt, false));
     }
     else {
-        //m_acl.reset(AgentConfig::getConfig().AccessControlManager.newPlugin(XML_ACCESS_CONTROL, e, deprecationSupport));
+        throw ConfigurationException("AttributeChecker requires either the attributes setting or path to ACL");
     }
 }
 
@@ -160,15 +132,15 @@ pair<bool,long> AttributeCheckerHandler::run(SPRequest& request, bool isHandler)
     bool checked = false;
     if (session) {
         if (!m_attributes.empty()) {
-            typedef multimap<string,const Attribute*> indexed_t;
-            static indexed_t::const_iterator (indexed_t::* fn)(const string&) const = &indexed_t::find;
-            const indexed_t& indexed = session->getIndexedAttributes();
+            const auto& indexed = session->getIndexedAttributes();
+            // Lambda returns true if the candidate attribute ID is NOT in the session.
+            auto absent = [&indexed](const string& id) {
+                return indexed.find(id) == indexed.end();
+            };
+
             // Look for an attribute in the list that is not in the session multimap.
             // If that fails, the check succeeds.
-            checked = (
-                find_if(m_attributes.begin(), m_attributes.end(),
-                    boost::bind(fn, boost::cref(indexed), _1) == indexed.end()) == m_attributes.end()
-                );
+            checked = find_if(m_attributes.begin(), m_attributes.end(), absent) == m_attributes.end();
         }
         else {
             checked = (m_acl && m_acl->authorized(request, session) == AccessControl::shib_acl_true);
@@ -181,37 +153,11 @@ pair<bool,long> AttributeCheckerHandler::run(SPRequest& request, bool isHandler)
         return make_pair(true, request.sendRedirect(loc.c_str()));
     }
 
-    request.setContentType("text/html; charset=UTF-8");
-    request.setResponseHeader("Expires","Wed, 01 Jan 1997 12:00:00 GMT");
-    request.setResponseHeader("Cache-Control","private,no-store,no-cache,max-age=0");
-
-    ifstream infile(m_template.c_str());
-    if (infile) {
-        /*
-        // If the externalParameters option isn't set, don't populate the request field.
-        pair<bool,bool> externalParameters =
-                props ? props->getBool("externalParameters") : pair<bool,bool>(false,false);
-        if (externalParameters.first && externalParameters.second) {
-            //tp.m_request = &request;
-        }
-        */
-
-        stringstream str;
-        //XMLToolingConfig::getConfig().getTemplateEngine()->run(infile, str, tp);
-        if (m_flushSession && session) {
-            time_t revocationExp = session->getExpiration();
-            sessionLocker.unlock(); // unlock the session
-            flushSession(request, revocationExp);
-        }
-        return make_pair(true, request.sendError(str));
-    }
-
     if (m_flushSession && session) {
         time_t revocationExp = session->getExpiration();
         sessionLocker.unlock(); // unlock the session
         flushSession(request, revocationExp);
     }
-    m_log.error("could not process error template (%s)", m_template.c_str());
-    istringstream msg("Internal Server Error. Please contact the site administrator.");
-    return make_pair(true, request.sendResponse(msg));
+
+    return make_pair(true, request.sendRedirect(m_redirectOnFailure.c_str()));
 }
diff --git a/shibsp/handler/impl/DiscoveryFeed.cpp b/shibsp/handler/impl/DiscoveryFeed.cpp
deleted file mode 100644
index 032cab5c..00000000
--- a/shibsp/handler/impl/DiscoveryFeed.cpp
+++ /dev/null
@@ -1,329 +0,0 @@
-/**
- * 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.
- *
- * 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
- *
- * 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.
- */
-
-/**
- * DiscoveryFeed.cpp
- *
- * Handler for generating a JSON discovery feed based on metadata.
- */
-
-#include "internal.h"
-#include "AgentConfig.h"
-#include "exceptions.h"
-#include "SPRequest.h"
-#include "handler/AbstractHandler.h"
-#include "handler/RemotedHandler.h"
-#include "util/PathResolver.h"
-
-#include <ctime>
-#include <fstream>
-#include <sstream>
-#include <xmltooling/XMLToolingConfig.h>
-#include <xmltooling/util/Threads.h>
-
-using namespace shibsp;
-using namespace xercesc;
-using namespace std;
-
-namespace shibsp {
-
-#if defined (_MSC_VER)
-    #pragma warning( push )
-    #pragma warning( disable : 4250 4251)
-#endif
-
-    class SHIBSP_DLLLOCAL Blocker : public DOMNodeFilter
-    {
-    public:
-        FilterAction acceptNode(const DOMNode* node) const {
-            return FILTER_REJECT;
-        }
-    };
-
-    static SHIBSP_DLLLOCAL Blocker g_Blocker;
-
-    class SHIBSP_API DiscoveryFeed : public AbstractHandler, public RemotedHandler
-    {
-    public:
-        DiscoveryFeed(const DOMElement* e, const char* appId);
-        virtual ~DiscoveryFeed();
-
-        pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-        void receive(DDF& in, ostream& out);
-
-    private:
-        void feedToFile(string& cacheTag) const;
-        void feedToStream(string& cacheTag, ostream& os) const;
-
-        string m_dir;
-        bool m_cacheToClient;
-#ifndef SHIBSP_LITE
-        // Application-specific queues of feed files, linked to the last time of "access".
-        // The key to the map is the application's "hash" code, not the ID itself.
-        // Each filename is also a cache tag.
-        typedef queue< pair<string, time_t> > feedqueue_t;
-        mutable map<string,feedqueue_t> m_feedQueues;
-        scoped_ptr<Mutex> m_feedLock;
-#endif
-    };
-
-#if defined (_MSC_VER)
-    #pragma warning( pop )
-#endif
-
-    Handler* SHIBSP_DLLLOCAL DiscoveryFeedFactory(const pair<const DOMElement*,const char*>& p, bool)
-    {
-        return new DiscoveryFeed(p.first, p.second);
-    }
-
-};
-
-DiscoveryFeed::DiscoveryFeed(const DOMElement* e, const char* appId)
-    : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT ".Handler.DiscoveryFeed"), &g_Blocker), m_cacheToClient(false)
-{
-    pair<bool,const char*> prop = getString("Location");
-    if (!prop.first)
-        throw ConfigurationException("DiscoveryFeed handler requires Location property.");
-    string address(appId);
-    address += prop.second;
-    setAddress(address.c_str());
-
-    pair<bool,bool> flag = getBool("cacheToClient");
-    m_cacheToClient = flag.first && flag.second;
-    flag = getBool("cacheToDisk");
-    if (!flag.first || flag.second) {
-        prop = getString("dir");
-        if (prop.first)
-            m_dir = prop.second;
-        AgentConfig::getConfig().getPathResolver().resolve(m_dir, PathResolver::SHIBSP_CACHE_FILE);
-        m_log.info("feed files will be cached in %s", m_dir.c_str());
-#ifndef SHIBSP_LITE
-        m_feedLock.reset(Mutex::create());
-#endif
-    }
-}
-
-DiscoveryFeed::~DiscoveryFeed()
-{
-#ifndef SHIBSP_LITE
-    if (m_feedLock.get()) {
-        // Remove any files unused for more than a couple of minutes.
-        time_t now = time(nullptr);
-        for (map<string, feedqueue_t>::iterator i = m_feedQueues.begin(); i != m_feedQueues.end(); ++i) {
-            while (!i->second.empty() && now - i->second.front().second > 60) {
-                string fname = m_dir + '/' + i->first + '_' + i->second.front().first + ".json";
-                remove(fname.c_str());
-                i->second.pop();
-            }
-        }
-    }
-#endif
-}
-
-pair<bool,long> DiscoveryFeed::run(SPRequest& request, bool isHandler) const
-{
-    try {
-        string s;
-        if (m_cacheToClient) {
-            s = request.getHeader("If-None-Match");
-        }
-
-        if (false) {
-            // When out of process, we run natively and directly process the message.
-            if (m_dir.empty()) {
-                // The feed is directly returned.
-                stringstream buf;
-                feedToStream(s, buf);
-                if (!s.empty()) {
-                    if (m_cacheToClient) {
-                        string etag = '"' + s + '"';
-                        request.setResponseHeader("ETag", etag.c_str());
-                    }
-                    request.setContentType("application/json; charset=UTF-8");
-                    return make_pair(true, request.sendResponse(buf));
-                }
-            }
-            else {
-                // Indirect the feed through a file.
-                feedToFile(s);
-            }
-        }
-        else {
-            // When not out of process, we remote all the message processing.
-            DDF out,in = DDF(m_address.c_str());
-            if (!s.empty())
-                in.addmember("cache_tag").string(s.c_str());
-            DDFJanitor jin(in), jout(out);
-            out = send(request, in);
-            s.erase();
-            if (m_dir.empty()) {
-                // The cache tag and feed are in the response struct.
-                if (m_cacheToClient && out["cache_tag"].string()) {
-                    string etag = string("\"") + out["cache_tag"].string() + '"';
-                    request.setResponseHeader("ETag", etag.c_str());
-                }
-                if (out["feed"].string()) {
-                    istringstream buf(out["feed"].string());
-                    request.setContentType("application/json; charset=UTF-8");
-                    return make_pair(true, request.sendResponse(buf));
-                }
-                throw ConfigurationException("Discovery feed was empty.");
-            }
-            else {
-                // The response object is a string containing the cache tag.
-                if (out.isstring() && out.string())
-                    s = out.string();
-            }
-        }
-
-        if (s.empty()) {
-            m_log.debug("client's cache tag matches our feed");
-            istringstream msg("Not Modified");
-            return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_NOTMODIFIED));
-        }
-
-        // TODO: uniqueify name
-        string fname = m_dir + '/' + /* request.getApplication().getHash() + '_' + */ s + ".json";
-        ifstream feed(fname.c_str());
-        if (!feed)
-            throw ConfigurationException("Unable to access cached feed.");
-        if (m_cacheToClient) {
-            string etag = '"' + s + '"';
-            request.setResponseHeader("ETag", etag.c_str());
-        }
-        request.setContentType("application/json; charset=UTF-8");
-        return make_pair(true, request.sendResponse(feed));
-    }
-    catch (std::exception& ex) {
-        request.log(Priority::SHIB_ERROR, string("error while processing request:") + ex.what());
-        istringstream msg("Discovery Request Failed");
-        return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
-    }
-}
-
-void DiscoveryFeed::receive(DDF& in, ostream& out)
-{
-    string cacheTag;
-    if (in["cache_tag"].string())
-        cacheTag = in["cache_tag"].string();
-
-    DDF ret(nullptr);
-    DDFJanitor jout(ret);
-
-    if (!m_dir.empty()) {
-        // We're relaying the feed through a file.
-        feedToFile(cacheTag);
-        if (!cacheTag.empty())
-            ret.string(cacheTag.c_str());
-    }
-    else {
-        // We're relaying the feed directly.
-        ostringstream os;
-        feedToStream(cacheTag, os);
-        if (!cacheTag.empty())
-            ret.addmember("cache_tag").string(cacheTag.c_str());
-        string feed = os.str();
-        if (!feed.empty())
-            ret.addmember("feed").string(feed.c_str());
-    }
-    out << ret;
-}
-
-void DiscoveryFeed::feedToFile(string& cacheTag) const
-{
-#ifndef SHIBSP_LITE
-    m_log.debug("processing discovery feed request");
-
-    DiscoverableMetadataProvider* m = dynamic_cast<DiscoverableMetadataProvider*>(application.getMetadataProvider(false));
-    if (!m)
-        m_log.warn("MetadataProvider missing or does not support discovery feed");
-    Locker locker(m);
-    string feedTag = m ? m->getCacheTag() : "empty";
-    if (cacheTag == ('"' + feedTag + '"')) {
-        // The client already has the same feed we do.
-        m_log.debug("client's cache tag matches our feed (%s)", feedTag.c_str());
-        cacheTag.erase();   // clear the tag to signal no change
-        return;
-    }
-
-    cacheTag = feedTag;
-
-    // The client is out of date or not caching, so we need to see if our copy is good.
-    Lock lock(m_feedLock);
-    time_t now = time(nullptr);
-
-    // Clean up as many old files as it's safe to do.
-    feedqueue_t& q = m_feedQueues[application.getHash()];
-    while (q.size() > 1 && (now - q.front().second > 60)) {
-        string fname = m_dir + '/' + application.getHash() + '_' + q.front().first + ".json";
-        remove(fname.c_str());
-        q.pop();
-    }
-
-    if (q.empty() || q.back().first != feedTag) {
-        // We're out of date.
-        string fname = m_dir + '/' + application.getHash() + '_' + feedTag + ".json";
-        ofstream ofile(fname.c_str());
-        if (!ofile)
-            throw ConfigurationException("Unable to create feed in ($1).", params(1,fname.c_str()));
-        bool first = true;
-        if (m)
-            m->outputFeed(ofile, first);
-        else
-            ofile << "[\n]";
-        ofile.close();
-        q.push(make_pair(feedTag, now));
-    }
-    else {
-        // Update the back of the queue.
-        q.back().second = now;
-    }
-#else
-    throw ConfigurationException("Build does not support discovery feed.");
-#endif
-}
-
-void DiscoveryFeed::feedToStream(string& cacheTag, ostream& os) const
-{
-#ifndef SHIBSP_LITE
-    m_log.debug("processing discovery feed request");
-
-    DiscoverableMetadataProvider* m = dynamic_cast<DiscoverableMetadataProvider*>(application.getMetadataProvider(false));
-    if (!m)
-        m_log.warn("MetadataProvider missing or does not support discovery feed");
-    Locker locker(m);
-    string feedTag = m ? m->getCacheTag() : "empty";
-    if (cacheTag == ('"' + feedTag + '"')) {
-        // The client already has the same feed we do.
-        m_log.debug("client's cache tag matches our feed (%s)", feedTag.c_str());
-        cacheTag.erase();   // clear the tag to signal no change
-        return;
-    }
-
-    cacheTag = feedTag;
-    bool first = true;
-    if (m)
-        m->outputFeed(os, first);
-    else
-        os << "[\n]";
-#else
-    throw ConfigurationException("Build does not support discovery feed.");
-#endif
-}
diff --git a/shibsp/handler/impl/LocalLogoutInitiator.cpp b/shibsp/handler/impl/LocalLogoutInitiator.cpp
index 697ffc06..1970ff88 100644
--- a/shibsp/handler/impl/LocalLogoutInitiator.cpp
+++ b/shibsp/handler/impl/LocalLogoutInitiator.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * LocalLogoutInitiator.cpp
+ * handler/impl/LocalLogoutInitiator.cpp
  * 
  * Logs out a session locally.
  */
@@ -30,12 +24,13 @@
 #include "SPRequest.h"
 #include "handler/AbstractHandler.h"
 #include "handler/LogoutInitiator.h"
+#include "logging/Category.h"
 #include "session/SessionCache.h"
 
 #include <mutex>
 
 using namespace shibsp;
-using namespace xercesc;
+using namespace boost::property_tree;
 using namespace std;
 
 namespace shibsp {
@@ -48,50 +43,25 @@ namespace shibsp {
     class SHIBSP_DLLLOCAL LocalLogoutInitiator : public AbstractHandler, public LogoutInitiator
     {
     public:
-        LocalLogoutInitiator(const DOMElement* e, const char* appId);
+        LocalLogoutInitiator(const ptree& pt);
         virtual ~LocalLogoutInitiator() {}
         
-        void setParent(const PropertySet* parent);
-        void receive(DDF& in, ostream& out);
         pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-
-    private:
-        pair<bool,long> doRequest(SPRequest& request, Session* session) const;
-
-        string m_appId;
     };
 
 #if defined (_MSC_VER)
     #pragma warning( pop )
 #endif
 
-    Handler* SHIBSP_DLLLOCAL LocalLogoutInitiatorFactory(const pair<const DOMElement*,const char*>& p, bool)
+    Handler* SHIBSP_DLLLOCAL LocalLogoutInitiatorFactory(const pair<ptree&,const char*>& p, bool)
     {
-        return new LocalLogoutInitiator(p.first, p.second);
+        return new LocalLogoutInitiator(p.first);
     }
 };
 
-LocalLogoutInitiator::LocalLogoutInitiator(const DOMElement* e, const char* appId)
-    : AbstractHandler(e, Category::getInstance(SHIBSP_LOGCAT ".LogoutInitiator.Local")), m_appId(appId)
+LocalLogoutInitiator::LocalLogoutInitiator(const ptree& pt)
+    : AbstractHandler(pt, Category::getInstance(SHIBSP_LOGCAT ".LogoutInitiator.Local"))
 {
-    pair<bool,const char*> loc = getString("Location");
-    if (loc.first) {
-        string address = string(appId) + loc.second + "::run::LocalLI";
-        setAddress(address.c_str());
-    }
-}
-
-void LocalLogoutInitiator::setParent(const PropertySet* parent)
-{
-    DOMPropertySet::setParent(parent);
-    pair<bool,const char*> loc = getString("Location");
-    if (loc.first) {
-        string address = m_appId + loc.second + "::run::LocalLI";
-        setAddress(address.c_str());
-    }
-    else {
-        m_log.warn("no Location property in Local LogoutInitiator (or parent), can't register as remoted handler");
-    }
 }
 
 pair<bool,long> LocalLogoutInitiator::run(SPRequest& request, bool isHandler) const
@@ -101,71 +71,15 @@ pair<bool,long> LocalLogoutInitiator::run(SPRequest& request, bool isHandler) co
     if (ret.first)
         return ret;
 
-    if (false) {
-        // When out of process, we run natively.
-        Session* session = nullptr;
-        try {
-            session = request.getSession(false, true, false);  // don't cache it and ignore all checks
-        }
-        catch (const std::exception& ex) {
-            m_log.error("error accessing current session: %s", ex.what());
-        }
-        return doRequest(request, session);
-    }
-    else {
-        // When not out of process, we remote the request.
-        vector<string> headers(1,"Cookie");
-        headers.push_back("User-Agent");
-        DDF out,in = wrap(request,&headers);
-        DDFJanitor jin(in), jout(out);
-        out = send(request, in);
-        return unwrap(request, out);
-    }
-}
-
-void LocalLogoutInitiator::receive(DDF& in, ostream& out)
-{
-#ifndef SHIBSP_LITE
-    // Defer to base class for back channel notifications
-    if (in["notify"].integer() == 1)
-        return LogoutHandler::receive(in, out);
-
-    // Find application.
-    const char* aid=in["application_id"].string();
-    const Application* app=aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
-    if (!app) {
-        // Something's horribly wrong.
-        m_log.error("couldn't find application (%s) for logout", aid ? aid : "(missing)");
-        throw ConfigurationException("Unable to locate application for logout, deleted?");
-    }
-
-    // Unpack the request.
-    scoped_ptr<HTTPRequest> req(getRequest(*app, in));
-
-    // Set up a response shim.
-    DDF ret(nullptr);
-    DDFJanitor jout(ret);
-    scoped_ptr<HTTPResponse> resp(getResponse(*app, ret));
-
+    // When out of process, we run natively.
     Session* session = nullptr;
     try {
-         session = app->getServiceProvider().getSessionCache()->find(*app, *req, nullptr, nullptr);
+        session = request.getSession(false, true, false);  // don't cache it and ignore all checks
     }
     catch (const std::exception& ex) {
         m_log.error("error accessing current session: %s", ex.what());
     }
 
-    // This is the "last chance" handler so even without a session, we "complete" the logout.
-    doRequest(*app, *req, *resp, session);
-
-    out << ret;
-#else
-    throw ConfigurationException("Cannot perform logout using lite version of shibsp library.");
-#endif
-}
-
-pair<bool,long> LocalLogoutInitiator::doRequest(SPRequest& request, Session* session) const
-{
     if (session) {
         // Guard the session in case of exception.
         unique_lock<Session> locker(*session, adopt_lock);
diff --git a/shibsp/handler/impl/LogoutHandler.cpp b/shibsp/handler/impl/LogoutHandler.cpp
index 46d27d4f..9197cc54 100644
--- a/shibsp/handler/impl/LogoutHandler.cpp
+++ b/shibsp/handler/impl/LogoutHandler.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * LogoutHandler.cpp
+ * handler/impl/LogoutHandler.cpp
  *
  * Base class for logout-related handlers.
  */
@@ -38,7 +32,6 @@
 #include <boost/lexical_cast.hpp>
 
 using namespace shibsp;
-using namespace xercesc;
 using namespace std;
 
 LogoutHandler::LogoutHandler() : m_initiator(true)
@@ -51,10 +44,6 @@ LogoutHandler::~LogoutHandler()
 
 pair<bool,long> LogoutHandler::run(SPRequest& request, bool isHandler) const
 {
-    // If we're inside a chain, do nothing.
-    if (getParent())
-        return make_pair(false,0L);
-
     // If this isn't a LogoutInitiator, we only "continue" a notification loop, rather than starting one.
     if (!m_initiator && !request.getParameter("notifying"))
         return make_pair(false,0L);
@@ -63,6 +52,7 @@ pair<bool,long> LogoutHandler::run(SPRequest& request, bool isHandler) const
     return notifyFrontChannel(request);
 }
 
+/*
 void LogoutHandler::receive(DDF& in, ostream& out)
 {
     DDF ret(nullptr);
@@ -82,6 +72,7 @@ void LogoutHandler::receive(DDF& in, ostream& out)
 
     out << ret;
 }
+*/
 
 pair<bool,long> LogoutHandler::notifyFrontChannel(
     SPRequest& request,
@@ -217,6 +208,7 @@ bool LogoutHandler::notifyBackChannel(const SPRequest& request, const vector<str
 #endif
     }
 
+/*
     // When not out of process, we remote the back channel work.
     // TODO: remove anyway....
     DDF out,in(m_address.c_str());
@@ -233,4 +225,5 @@ bool LogoutHandler::notifyBackChannel(const SPRequest& request, const vector<str
     }
     //out = application.getServiceProvider().getListenerService()->send(in);
     return (out.integer() == 1);
+*/
 }
diff --git a/shibsp/handler/impl/LogoutInitiator.cpp b/shibsp/handler/impl/LogoutInitiator.cpp
index 432579ef..5aaacd83 100644
--- a/shibsp/handler/impl/LogoutInitiator.cpp
+++ b/shibsp/handler/impl/LogoutInitiator.cpp
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/handler/impl/MetadataGenerator.cpp b/shibsp/handler/impl/MetadataGenerator.cpp
index d2767961..934060f5 100644
--- a/shibsp/handler/impl/MetadataGenerator.cpp
+++ b/shibsp/handler/impl/MetadataGenerator.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * MetadataGenerator.cpp
+ * handler/impl/MetadataGenerator.cpp
  *
  * Handler for generating "approximate" metadata based on SP configuration.
  */
@@ -27,16 +21,16 @@
 #include "internal.h"
 #include "exceptions.h"
 #include "SPRequest.h"
-#include "handler/RemotedHandler.h"
 #include "handler/SecuredHandler.h"
+#include "logging/Category.h"
 
 #include <sstream>
-#include <boost/scoped_ptr.hpp>
-#include <boost/iterator/indirect_iterator.hpp>
+#include <string>
+#include <vector>
+#include <boost/algorithm/string.hpp>
 
 using namespace shibsp;
-using namespace boost;
-using namespace xercesc;
+using namespace boost::property_tree;
 using namespace std;
 
 namespace shibsp {
@@ -46,294 +40,35 @@ namespace shibsp {
     #pragma warning( disable : 4250 )
 #endif
 
-    class SHIBSP_API MetadataGenerator : public SecuredHandler, public RemotedHandler
+    class SHIBSP_API MetadataGenerator : public SecuredHandler
     {
     public:
-        MetadataGenerator(const DOMElement* e, const char* appId);
+        MetadataGenerator(const ptree& pt);
         virtual ~MetadataGenerator() {}
 
         pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-        void receive(DDF& in, ostream& out);
 
     private:
-        pair<bool,long> processMessage(
-            const char* handlerURL,
-            const char* entityID,
-            HTTPResponse& httpResponse
-            ) const;
-
-#ifndef SHIBSP_LITE
-        void registerEncryptionMethod(const XMLCh* alg) {
-            if (XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_ENCRYPT) ||
-                XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_KEYENCRYPT) ||
-                XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_KEYAGREE)) {
-                // Non-default builder needed to override namespace/prefix.
-                if (!m_encryptionBuilder)
-                    m_encryptionBuilder = XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_NS, EncryptionMethod::LOCAL_NAME));
-                EncryptionMethod* em = dynamic_cast<EncryptionMethod*>(
-                    m_encryptionBuilder->buildObject(
-                        samlconstants::SAML20MD_NS, EncryptionMethod::LOCAL_NAME, samlconstants::SAML20MD_PREFIX
-                        )
-                    );
-                em->setAlgorithm(alg);
-                m_encryptions.push_back(em);
-
-                if (
-#ifdef URI_ID_RSA_OAEP
-                    XMLString::equals(alg, DSIGConstants::s_unicodeStrURIRSA_OAEP) ||
-#endif
-                    XMLString::equals(alg, DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1)) {
-                    // Check for non-support of SHA-256. This is a reasonable guess as to whether
-                    // "all" standard digests and MGF variants will be supported or not, and if not, we
-                    // explicitly advertise only SHA-1.
-                    if (!XMLToolingConfig::getConfig().isXMLAlgorithmSupported(DSIGConstants::s_unicodeStrURISHA256, XMLToolingConfig::ALGTYPE_DIGEST)) {
-                        if (!m_digestBuilder)
-                            m_digestBuilder = XMLObjectBuilder::getBuilder(xmltooling::QName(samlconstants::SAML20MD_ALGSUPPORT_NS, DigestMethod::LOCAL_NAME));
-                        
-#ifdef URI_ID_RSA_OAEP
-                        // Add MGF for new OAEP variant.
-                        if (XMLString::equals(alg, DSIGConstants::s_unicodeStrURIRSA_OAEP)) {
-                            MGF* mgf = MGFBuilder::buildMGF();
-                            mgf->setAlgorithm(DSIGConstants::s_unicodeStrURIMGF1_SHA1);
-                            em->getUnknownXMLObjects().push_back(mgf);
-                        }
-#endif
-
-                        DigestMethod* dm = dynamic_cast<DigestMethod*>(
-                            m_digestBuilder->buildObject(xmlconstants::XMLSIG_NS, DigestMethod::LOCAL_NAME, xmlconstants::XMLSIG_PREFIX)
-                            );
-                        dm->setAlgorithm(DSIGConstants::s_unicodeStrURISHA1);
-                        em->getUnknownXMLObjects().push_back(dm);
-                    }
-                }
-            }
-        }
-
-        void registerDigestMethod(const XMLCh* alg) {
-            if (XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_DIGEST)) {
-                DigestMethod* dm = DigestMethodBuilder::buildDigestMethod();
-                dm->setAlgorithm(alg);
-                m_digests.push_back(dm);
-            }
-        }
-
-        void registerSigningMethod(const XMLCh* alg) {
-            if (XMLToolingConfig::getConfig().isXMLAlgorithmSupported(alg, XMLToolingConfig::ALGTYPE_SIGN)) {
-                SigningMethod* sm = SigningMethodBuilder::buildSigningMethod();
-                sm->setAlgorithm(alg);
-                m_signings.push_back(sm);
-            }
-        }
-
-        string m_salt;
-        short m_http,m_https;
         vector<string> m_bases;
-        scoped_ptr<UIInfo> m_uiinfo;
-        scoped_ptr<Organization> m_org;
-        scoped_ptr<EntityAttributes> m_entityAttrs;
-        ptr_vector<ContactPerson> m_contacts;
-        ptr_vector<NameIDFormat> m_formats;
-        ptr_vector<RequestedAttribute> m_reqAttrs;
-        ptr_vector<AttributeConsumingService> m_attrConsumers;
-        ptr_vector<EncryptionMethod> m_encryptions;
-        ptr_vector<DigestMethod> m_digests;
-        ptr_vector<SigningMethod> m_signings;
-        const XMLObjectBuilder* m_encryptionBuilder;
-        const XMLObjectBuilder* m_digestBuilder;
-#endif
     };
 
 #if defined (_MSC_VER)
     #pragma warning( pop )
 #endif
 
-    Handler* SHIBSP_DLLLOCAL MetadataGeneratorFactory(const pair<const DOMElement*,const char*>& p, bool)
+    Handler* SHIBSP_DLLLOCAL MetadataGeneratorFactory(const pair<ptree&,const char*>& p, bool)
     {
-        return new MetadataGenerator(p.first, p.second);
+        return new MetadataGenerator(p.first);
     }
 
 };
 
-MetadataGenerator::MetadataGenerator(const DOMElement* e, const char* appId)
-    : SecuredHandler(e, Category::getInstance(SHIBSP_LOGCAT ".Handler.Metadata"))
-#ifndef SHIBSP_LITE
-        ,m_http(0), m_https(0), m_encryptionBuilder(nullptr), m_digestBuilder(nullptr)
-#endif
+MetadataGenerator::MetadataGenerator(const ptree& pt)
+    : SecuredHandler(pt, Category::getInstance(SHIBSP_LOGCAT ".Handler.Metadata"))
 {
-    //SPConfig::getConfig().deprecation().warn(METADATA_GENERATOR_HANDLER" handler");
-
-    string address(appId);
-    address += getString("Location").second;
-    setAddress(address.c_str());
-
-#ifndef SHIBSP_LITE
-    static XMLCh EndpointBase[] =           UNICODE_LITERAL_12(E,n,d,p,o,i,n,t,B,a,s,e);
-
-    pair<bool,const char*> salt = getString("salt");
-    if (salt.first)
-        m_salt = salt.second;
-
-    pair<bool,bool> flag = getBool("http");
-    if (flag.first)
-        m_http = flag.second ? 1 : -1;
-    flag = getBool("https");
-    if (flag.first)
-        m_https = flag.second ? 1 : -1;
-
-    e = XMLHelper::getFirstChildElement(e);
-    while (e) {
-        if (XMLString::equals(e->getLocalName(), EndpointBase) && e->hasChildNodes()) {
-            auto_ptr_char base(e->getFirstChild()->getNodeValue());
-            if (base.get() && *base.get())
-                m_bases.push_back(base.get());
-        }
-        else {
-            // Try and parse the object.
-            auto_ptr<XMLObject> child(XMLObjectBuilder::buildOneFromElement(const_cast<DOMElement*>(e)));
-            ContactPerson* cp = dynamic_cast<ContactPerson*>(child.get());
-            if (cp) {
-                m_contacts.push_back(cp);
-                child.release();
-            }
-            else {
-                NameIDFormat* nif = dynamic_cast<NameIDFormat*>(child.get());
-                if (nif) {
-                    m_formats.push_back(nif);
-                    child.release();
-                }
-                else {
-                    RequestedAttribute* req = dynamic_cast<RequestedAttribute*>(child.get());
-                    if (req) {
-                        m_reqAttrs.push_back(req);
-                        child.release();
-                    }
-                    else {
-                        AttributeConsumingService* acs = dynamic_cast<AttributeConsumingService*>(child.get());
-                        if (acs) {
-                            m_attrConsumers.push_back(acs);
-                            child.release();
-                        }
-                        else {
-                            UIInfo* info = dynamic_cast<UIInfo*>(child.get());
-                            if (info) {
-                                if (!m_uiinfo) {
-                                    m_uiinfo.reset(info);
-                                    child.release();
-                                }
-                                else {
-                                    m_log.warn("skipping duplicate UIInfo element");
-                                }
-                            }
-                            else {
-                                Organization* org = dynamic_cast<Organization*>(child.get());
-                                if (org) {
-                                    if (!m_org) {
-                                        m_org.reset(org);
-                                        child.release();
-                                    }
-                                    else {
-                                        m_log.warn("skipping duplicate Organization element");
-                                    }
-                                }
-                                else {
-                                    EntityAttributes* ea = dynamic_cast<EntityAttributes*>(child.get());
-                                    if (ea) {
-                                        if (!m_entityAttrs) {
-                                            m_entityAttrs.reset(ea);
-                                            child.release();
-                                        }
-                                        else {
-                                            m_log.warn("skipping duplicate EntityAttributes element");
-                                        }
-                                    }
-                                    else {
-                                        EncryptionMethod* em = dynamic_cast<EncryptionMethod*>(child.get());
-                                        if (em) {
-                                            m_encryptions.push_back(em);
-                                            child.release();
-                                        }
-                                        else {
-                                            DigestMethod* dm = dynamic_cast<DigestMethod*>(child.get());
-                                            if (dm) {
-                                                m_digests.push_back(dm);
-                                                child.release();
-                                            }
-                                            else {
-                                                SigningMethod* sm = dynamic_cast<SigningMethod*>(child.get());
-                                                if (sm) {
-                                                    m_signings.push_back(sm);
-                                                    child.release();
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        e = XMLHelper::getNextSiblingElement(e);
-    }
-
-    // Default in precedence rules for various algorithms.
-    if (m_encryptions.empty()) {
-#ifdef XSEC_OPENSSL_HAVE_GCM
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES128_GCM);
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES192_GCM);
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES256_GCM);
-#endif
-#ifdef XSEC_OPENSSL_HAVE_AES
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES128_CBC);
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES192_CBC);
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIAES256_CBC);
-#endif
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURI3DES_CBC);
-#ifdef URI_ID_RSA_OAEP
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIRSA_OAEP);
-#endif
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIRSA_OAEP_MGFP1);
-        registerEncryptionMethod(DSIGConstants::s_unicodeStrURIRSA_1_5);
-    }
-
-    if (m_digests.empty()) {
-#ifdef XSEC_OPENSSL_HAVE_SHA2
-        registerDigestMethod(DSIGConstants::s_unicodeStrURISHA512);
-        registerDigestMethod(DSIGConstants::s_unicodeStrURISHA384);
-        registerDigestMethod(DSIGConstants::s_unicodeStrURISHA256);
-        registerDigestMethod(DSIGConstants::s_unicodeStrURISHA224);
-#endif
-        registerDigestMethod(DSIGConstants::s_unicodeStrURISHA1);
-    }
-
-    if (m_signings.empty()) {
-#ifdef XSEC_OPENSSL_HAVE_SHA2
-# ifdef XSEC_OPENSSL_HAVE_EC
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA512);
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA384);
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA256);
-#  ifdef URI_ID_ECDSA_SHA224
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA224);
-#  endif
-# endif
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA512);
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA384);
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA256);
-
-# ifdef URI_ID_DSA_SHA256
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIDSA_SHA256);
-# endif
-#endif
-
-
-#ifdef XSEC_OPENSSL_HAVE_EC
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIECDSA_SHA1);
-#endif
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIRSA_SHA1);
-        registerSigningMethod(DSIGConstants::s_unicodeStrURIDSA_SHA1);
-    }
-#endif
+    string bases(getString("baseURLs", ""));
+    boost::trim(bases);
+    boost::split(m_bases, bases, boost::is_space(), boost::algorithm::token_compress_on);
 }
 
 pair<bool,long> MetadataGenerator::run(SPRequest& request, bool isHandler) const
@@ -344,322 +79,11 @@ pair<bool,long> MetadataGenerator::run(SPRequest& request, bool isHandler) const
         return ret;
 
     try {
-        if (false) {
-            // When out of process, we run natively and directly process the message.
-            return processMessage(request.getHandlerURL(), request.getParameter("entityID"), request);
-        }
-        else {
-            // When not out of process, we remote all the message processing.
-            DDF out,in = DDF(m_address.c_str());
-            in.addmember("handler_url").string(request.getHandlerURL());
-            if (request.getParameter("entityID"))
-                in.addmember("entity_id").string(request.getParameter("entityID"));
-            DDFJanitor jin(in), jout(out);
-
-            out = send(request, in);
-            return unwrap(request, out);
-        }
+        // TODO
     }
-    catch (std::exception& ex) {
+    catch (exception& ex) {
         m_log.error("error while processing request: %s", ex.what());
         istringstream msg("Metadata Request Failed");
         return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
     }
 }
-
-void MetadataGenerator::receive(DDF& in, ostream& out)
-{
-    /*
-    const char* hurl = in["handler_url"].string();
-    if (!hurl) {
-        throw ConfigurationException("Missing handler_url parameter in remoted method call.");
-    }
-
-    // Wrap a response shim.
-    DDF ret(nullptr);
-    DDFJanitor jout(ret);
-    scoped_ptr<HTTPResponse> resp(getResponse(*app, ret));
-
-    // Since we're remoted, the result should either be a throw, a false/0 return,
-    // which we just return as an empty structure, or a response/redirect,
-    // which we capture in the facade and send back.
-    processMessage(hurl, in["entity_id"].string(), *resp);
-    out << ret;
-    */
-}
-
-pair<bool,long> MetadataGenerator::processMessage(const char* handlerURL, const char* entityID, HTTPResponse& httpResponse) const
-{
-#ifndef SHIBSP_LITE
-    m_log.debug("processing metadata request");
-
-    const PropertySet* relyingParty = nullptr;
-    if (entityID) {
-        MetadataProvider* m = application.getMetadataProvider();
-        Locker locker(m);
-        MetadataProviderCriteria mc(application, entityID);
-        relyingParty = application.getRelyingParty(m->getEntityDescriptor(mc).first);
-    }
-    else {
-        relyingParty = &application;
-    }
-
-    scoped_ptr<EntityDescriptor> entity;
-    pair<bool,const char*> prop = getString("template");
-    if (prop.first) {
-        // Load a template to use for our metadata.
-        string templ(prop.second);
-        XMLToolingConfig::getConfig().getPathResolver()->resolve(templ, PathResolver::XMLTOOLING_CFG_FILE);
-        auto_ptr_XMLCh widenit(templ.c_str());
-        LocalFileInputSource src(widenit.get());
-        Wrapper4InputSource dsrc(&src,false);
-        DOMDocument* doc = XMLToolingConfig::getConfig().getParser().parse(dsrc);
-        XercesJanitor<DOMDocument> docjan(doc);
-        auto_ptr<XMLObject> xmlobj(XMLObjectBuilder::buildOneFromElement(doc->getDocumentElement(), true));
-        docjan.release();
-        entity.reset(dynamic_cast<EntityDescriptor*>(xmlobj.get()));
-        xmlobj.release();
-        if (!entity)
-            throw ConfigurationException("Template file ($1) did not contain an EntityDescriptor", params(1, templ.c_str()));
-    }
-    else {
-        entity.reset(EntityDescriptorBuilder::buildEntityDescriptor());
-    }
-
-    // We always have extensions for algorithm support.
-    if (!entity->getExtensions()) {
-        entity->setExtensions(ExtensionsBuilder::buildExtensions());
-        entity->getExtensions()->addNamespace(Namespace(samlconstants::SAML20MD_ALGSUPPORT_NS, samlconstants::SAML20MD_ALGSUPPORT_PREFIX));
-    }
-
-    if (!entity->getID()) {
-        string hashinput = m_salt + relyingParty->getString("entityID").second;
-        string hashed = '_' + SecurityHelper::doHash("SHA1", hashinput.c_str(), hashinput.length());
-        auto_ptr_XMLCh widenit(hashed.c_str());
-        entity->setID(widenit.get());
-    }
-
-    pair<bool,unsigned int> cache = getUnsignedInt("cacheDuration");
-    if (cache.first) {
-        entity->setCacheDuration(cache.second);
-    }
-    cache = getUnsignedInt("validUntil");
-    if (cache.first)
-        entity->setValidUntil(time(nullptr) + cache.second);
-    entity->setEntityID(relyingParty->getXMLString("entityID").second);
-
-    if (m_org && !entity->getOrganization())
-        entity->setOrganization(m_org->cloneOrganization());
-
-    for (ptr_vector<ContactPerson>::const_iterator cp = m_contacts.begin(); cp != m_contacts.end(); ++cp)
-        entity->getContactPersons().push_back(cp->cloneContactPerson());
-
-    if (m_entityAttrs) {
-        entity->getExtensions()->getUnknownXMLObjects().push_back(m_entityAttrs->cloneEntityAttributes());
-    }
-
-    SPSSODescriptor* role;
-    if (entity->getSPSSODescriptors().empty()) {
-        role = SPSSODescriptorBuilder::buildSPSSODescriptor();
-        entity->getSPSSODescriptors().push_back(role);
-    }
-    else {
-        role = entity->getSPSSODescriptors().front();
-    }
-
-    for (ptr_vector<NameIDFormat>::const_iterator nif = m_formats.begin(); nif != m_formats.end(); ++nif)
-        role->getNameIDFormats().push_back(nif->cloneNameIDFormat());
-
-    if (m_uiinfo) {
-        if (!role->getExtensions())
-            role->setExtensions(ExtensionsBuilder::buildExtensions());
-        role->getExtensions()->getUnknownXMLObjects().push_back(m_uiinfo->cloneUIInfo());
-    }
-
-    if (!m_digests.empty() || !m_signings.empty()) {
-        for (ptr_vector<DigestMethod>::const_iterator dm = m_digests.begin(); dm != m_digests.end(); ++dm)
-            entity->getExtensions()->getUnknownXMLObjects().push_back(dm->cloneDigestMethod());
-        for (ptr_vector<SigningMethod>::const_iterator sm = m_signings.begin(); sm != m_signings.end(); ++sm)
-            entity->getExtensions()->getUnknownXMLObjects().push_back(sm->cloneSigningMethod());
-    }
-
-    for (ptr_vector<AttributeConsumingService>::const_iterator acs = m_attrConsumers.begin(); acs != m_attrConsumers.end(); ++acs)
-        role->getAttributeConsumingServices().push_back(acs->cloneAttributeConsumingService());
-
-    if (!m_reqAttrs.empty()) {
-        int index = 1;
-        const vector<AttributeConsumingService*>& svcs = const_cast<const SPSSODescriptor*>(role)->getAttributeConsumingServices();
-        for (indirect_iterator<vector<AttributeConsumingService*>::const_iterator> s = make_indirect_iterator(svcs.begin());
-                s != make_indirect_iterator(svcs.end()); ++s) {
-            pair<bool,int> i = s->getIndex();
-            if (i.first && index == i.second)
-                index = i.second + 1;
-        }
-        AttributeConsumingService* svc = AttributeConsumingServiceBuilder::buildAttributeConsumingService();
-        role->getAttributeConsumingServices().push_back(svc);
-        svc->setIndex(index);
-        ServiceName* sn = ServiceNameBuilder::buildServiceName();
-        svc->getServiceNames().push_back(sn);
-        sn->setName(entity->getEntityID());
-        static const XMLCh english[] = UNICODE_LITERAL_2(e,n);
-        sn->setLang(english);
-        for (ptr_vector<RequestedAttribute>::const_iterator req = m_reqAttrs.begin(); req != m_reqAttrs.end(); ++req)
-            svc->getRequestedAttributes().push_back(req->cloneRequestedAttribute());
-    }
-
-    // Policy flags.
-    prop = relyingParty->getString("signing");
-    if (prop.first && (!strcmp(prop.second,"true") || !strcmp(prop.second,"front")))
-        role->AuthnRequestsSigned(true);
-    pair<bool,bool> flagprop = relyingParty->getBool("requireSignedAssertions");
-    if (flagprop.first && flagprop.second)
-        role->WantAssertionsSigned(true);
-
-    // Ask each handler to generate itself.
-    vector<const Handler*> handlers;
-    application.getHandlers(handlers);
-    for (indirect_iterator<vector<const Handler*>::const_iterator> h = make_indirect_iterator(handlers.begin());
-            h != make_indirect_iterator(handlers.end()); ++h) {
-        if (m_bases.empty()) {
-            if (strncmp(handlerURL, "https", 5) == 0) {
-                if (m_https >= 0)
-                    h->generateMetadata(*role, handlerURL);
-                if (m_http == 1) {
-                    string temp(handlerURL);
-                    temp.erase(4, 1);
-                    h->generateMetadata(*role, temp.c_str());
-                }
-            }
-            else {
-                if (m_http >= 0)
-                    h->generateMetadata(*role, handlerURL);
-                if (m_https == 1) {
-                    string temp(handlerURL);
-                    temp.insert(temp.begin() + 4, 's');
-                    h->generateMetadata(*role, temp.c_str());
-                }
-            }
-        }
-        else {
-            for (vector<string>::const_iterator b = m_bases.begin(); b != m_bases.end(); ++b)
-                h->generateMetadata(*role, b->c_str());
-        }
-    }
-
-    AttributeExtractor* extractor = application.getAttributeExtractor();
-    if (extractor) {
-        Locker extlocker(extractor);
-        extractor->generateMetadata(*role);
-    }
-
-    CredentialResolver* credResolver = application.getCredentialResolver();
-    if (credResolver) {
-        Locker credLocker(credResolver);
-        CredentialCriteria cc;
-        prop = relyingParty->getString("keyName");
-        if (prop.first)
-            cc.getKeyNames().insert(prop.second);
-        vector<const Credential*> signingcreds,enccreds;
-        cc.setUsage(Credential::SIGNING_CREDENTIAL);
-        credResolver->resolve(signingcreds, &cc);
-        cc.setUsage(Credential::ENCRYPTION_CREDENTIAL);
-        credResolver->resolve(enccreds, &cc);
-
-        for (vector<const Credential*>::const_iterator c = signingcreds.begin(); c != signingcreds.end(); ++c) {
-            KeyInfo* kinfo = (*c)->getKeyInfo();
-            if (kinfo) {
-                KeyDescriptor* kd = KeyDescriptorBuilder::buildKeyDescriptor();
-                kd->setKeyInfo(kinfo);
-                const XMLCh* use = KeyDescriptor::KEYTYPE_SIGNING;
-                for (vector<const Credential*>::iterator match = enccreds.begin(); match != enccreds.end(); ++match) {
-                    if (*match == *c) {
-                        use = nullptr;
-                        enccreds.erase(match);
-                        break;
-                    }
-                }
-                kd->setUse(use);
-                if (!use) {
-                    for (ptr_vector<EncryptionMethod>::const_iterator em = m_encryptions.begin(); em != m_encryptions.end(); ++em)
-                        kd->getEncryptionMethods().push_back(em->cloneEncryptionMethod());
-                }
-                role->getKeyDescriptors().push_back(kd);
-            }
-        }
-
-        for (vector<const Credential*>::const_iterator c = enccreds.begin(); c != enccreds.end(); ++c) {
-            KeyInfo* kinfo = (*c)->getKeyInfo();
-            if (kinfo) {
-                KeyDescriptor* kd = KeyDescriptorBuilder::buildKeyDescriptor();
-                kd->setUse(KeyDescriptor::KEYTYPE_ENCRYPTION);
-                kd->setKeyInfo(kinfo);
-                for (ptr_vector<EncryptionMethod>::const_iterator em = m_encryptions.begin(); em != m_encryptions.end(); ++em)
-                    kd->getEncryptionMethods().push_back(em->cloneEncryptionMethod());
-                role->getKeyDescriptors().push_back(kd);
-            }
-        }
-    }
-
-    // Stream for response.
-    stringstream s;
-
-    // Self-sign it?
-    pair<bool,bool> flag = getBool("signing");
-    if (flag.first && flag.second) {
-        if (credResolver) {
-            Locker credLocker(credResolver);
-            // Fill in criteria to use.
-            CredentialCriteria cc;
-            cc.setUsage(Credential::SIGNING_CREDENTIAL);
-            prop = getString("keyName");
-            if (prop.first)
-                cc.getKeyNames().insert(prop.second);
-            pair<bool,const XMLCh*> sigalg = getXMLString("signingAlg");
-            pair<bool,const XMLCh*> digalg = getXMLString("digestAlg");
-            if (sigalg.first)
-                cc.setXMLAlgorithm(sigalg.second);
-            const Credential* cred = credResolver->resolve(&cc);
-            if (!cred)
-                throw XMLSecurityException("Unable to obtain signing credential to use.");
-
-            // Pretty-print it first and then read it back in.
-            stringstream pretty;
-            XMLHelper::serialize(entity->marshall(), pretty, true);
-            DOMDocument* prettydoc = XMLToolingConfig::getConfig().getParser().parse(pretty);
-            scoped_ptr<XMLObject> prettyentity(XMLObjectBuilder::buildOneFromElement(prettydoc->getDocumentElement(), true));
-
-            Signature* sig = SignatureBuilder::buildSignature();
-            dynamic_cast<EntityDescriptor*>(prettyentity.get())->setSignature(sig);
-            if (sigalg.first)
-                sig->setSignatureAlgorithm(sigalg.second);
-            if (digalg.first) {
-                opensaml::ContentReference* cr = dynamic_cast<opensaml::ContentReference*>(sig->getContentReference());
-                if (cr)
-                    cr->setDigestAlgorithm(digalg.second);
-            }
-
-            // Sign while marshalling.
-            vector<Signature*> sigs(1,sig);
-            prettyentity->marshall(prettydoc,&sigs,cred);
-            s << "<!--" << endl << "This is example metadata only. Do *NOT* supply it as is without review,"
-                << endl << "and do *NOT* provide it in real time to your partners." << endl << " -->" << endl;
-            s << *prettyentity;
-        }
-        else {
-            throw FatalProfileException("Can't self-sign metadata, no credential resolver found.");
-        }
-    }
-    else {
-        // Pretty-print it directly to client.
-        s << "<!--" << endl << "This is example metadata only. Do *NOT* supply it as is without review,"
-            << endl << "and do *NOT* provide it in real time to your partners." << endl << " -->";
-        XMLHelper::serialize(entity->marshall(), s, true);
-    }
-
-    prop = getString("mimeType");
-    httpResponse.setContentType(prop.first ? prop.second : "application/samlmetadata+xml");
-    return make_pair(true, httpResponse.sendResponse(s));
-#else
-    return make_pair(false, 0L);
-#endif
-}
diff --git a/shibsp/handler/impl/RemotedHandler.cpp b/shibsp/handler/impl/RemotedHandler.cpp
index ce02b773..eddfefcb 100644
--- a/shibsp/handler/impl/RemotedHandler.cpp
+++ b/shibsp/handler/impl/RemotedHandler.cpp
@@ -13,7 +13,7 @@
  */
 
 /**
- * RemotedHandler.cpp
+ * handler/impl/RemotedHandler.cpp
  * 
  * Base class for handlers that need SP request/response layer to be remoted. 
  */
diff --git a/shibsp/handler/impl/SAML2Consumer.cpp b/shibsp/handler/impl/SAML2Consumer.cpp
index 9728b69d..089b56e4 100644
--- a/shibsp/handler/impl/SAML2Consumer.cpp
+++ b/shibsp/handler/impl/SAML2Consumer.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * SAML2Consumer.cpp
+ * handler/impl/SAML2Consumer.cpp
  *
  * SAML 2.0 assertion consumer service.
  */
diff --git a/shibsp/handler/impl/SAML2Logout.cpp b/shibsp/handler/impl/SAML2Logout.cpp
index b2b3c00e..485c0474 100644
--- a/shibsp/handler/impl/SAML2Logout.cpp
+++ b/shibsp/handler/impl/SAML2Logout.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * SAML2Logout.cpp
+ * handler/impl/SAML2Logout.cpp
  *
  * Handles SAML 2.0 single logout protocol messages.
  */
diff --git a/shibsp/handler/impl/SAML2LogoutInitiator.cpp b/shibsp/handler/impl/SAML2LogoutInitiator.cpp
index 448bf6cf..dc7bc388 100644
--- a/shibsp/handler/impl/SAML2LogoutInitiator.cpp
+++ b/shibsp/handler/impl/SAML2LogoutInitiator.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * SAML2LogoutInitiator.cpp
+ * handler/impl/SAML2LogoutInitiator.cpp
  *
  * Triggers SP-initiated logout for SAML 2.0 sessions.
  */
diff --git a/shibsp/handler/impl/SAML2SessionInitiator.cpp b/shibsp/handler/impl/SAML2SessionInitiator.cpp
index 5459501c..d8d32e56 100644
--- a/shibsp/handler/impl/SAML2SessionInitiator.cpp
+++ b/shibsp/handler/impl/SAML2SessionInitiator.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * SAML2SessionInitiator.cpp
+ * handler/impl/SAML2SessionInitiator.cpp
  *
  * SAML 2.0 AuthnRequest support.
  */
diff --git a/shibsp/handler/impl/SAMLDSSessionInitiator.cpp b/shibsp/handler/impl/SAMLDSSessionInitiator.cpp
index 28fd875f..882d462a 100644
--- a/shibsp/handler/impl/SAMLDSSessionInitiator.cpp
+++ b/shibsp/handler/impl/SAMLDSSessionInitiator.cpp
@@ -13,7 +13,7 @@
  */
 
 /**
- * SAMLDSSessionInitiator.cpp
+ * handler/impl/SAMLDSSessionInitiator.cpp
  *
  * SAML Discovery Service support.
  */
diff --git a/shibsp/handler/impl/SecuredHandler.cpp b/shibsp/handler/impl/SecuredHandler.cpp
index be44baec..f2c6e62d 100644
--- a/shibsp/handler/impl/SecuredHandler.cpp
+++ b/shibsp/handler/impl/SecuredHandler.cpp
@@ -27,51 +27,27 @@
 #include "internal.h"
 #include "SPRequest.h"
 #include "handler/SecuredHandler.h"
+#include "logging/Category.h"
 
-#define BOOST_BIND_GLOBAL_PLACEHOLDERS
-#include <boost/bind.hpp>
 #include <boost/algorithm/string.hpp>
 
 #include <sstream>
 
 using namespace shibsp;
-using namespace boost;
-using namespace xercesc;
+using namespace boost::property_tree;
 using namespace std;
 
-namespace {
-    class SHIBSP_DLLLOCAL Blocker : public DOMNodeFilter
-    {
-    public:
-        FilterAction acceptNode(const DOMNode* node) const {
-            return FILTER_REJECT;
-        }
-    };
-
-    static Blocker g_Blocker;
-};
-
-SecuredHandler::SecuredHandler(
-    const DOMElement* e,
-    Category& log,
-    const char* aclProperty,
-    const char* defaultACL,
-    DOMNodeFilter* filter,
-    const Remapper* remapper
-    ) : AbstractHandler(e, log, filter ? filter : &g_Blocker, remapper)
+SecuredHandler::SecuredHandler(const ptree& pt, Category& log, const char* aclProperty, const char* defaultACL)
+    : AbstractHandler(pt, log)
 {
-    pair<bool,const char*> acl = getString(aclProperty);
-    if (!acl.first && defaultACL) {
-        m_log.info("installing default ACL (%s)", defaultACL);
-        acl.first = true;
-        acl.second = defaultACL;
-    }
-    if (acl.first) {
-        string aclbuf(acl.second);
-        trim(aclbuf);
+    const char* acl = getString(aclProperty, defaultACL);
+    if (acl) {
+        string aclbuf(acl);
+        boost::trim(aclbuf);
         vector<string> aclarray;
-        split(aclarray, aclbuf, is_space(), algorithm::token_compress_on);
-        for_each(aclarray.begin(), aclarray.end(), boost::bind(&SecuredHandler::parseACL, this, _1));
+        boost::split(aclarray, aclbuf, boost::is_space(), boost::algorithm::token_compress_on);
+        for_each(aclarray.begin(), aclarray.end(), [this](const string& s){parseACL(s);});
+
         if (m_acl.empty()) {
             m_log.warn("invalid CIDR range(s) in handler's acl property, allowing 127.0.0.1 and ::1 as a fall back");
             m_acl.push_back(IPRange::parseCIDRBlock("127.0.0.1"));
@@ -89,7 +65,7 @@ void SecuredHandler::parseACL(const string& acl)
     try {
         m_acl.push_back(IPRange::parseCIDRBlock(acl.c_str()));
     }
-    catch (std::exception& ex) {
+    catch (exception& ex) {
         m_log.error("invalid CIDR block (%s): %s", acl.c_str(), ex.what());
     }
 }
@@ -97,8 +73,11 @@ void SecuredHandler::parseACL(const string& acl)
 pair<bool,long> SecuredHandler::run(SPRequest& request, bool isHandler) const
 {
     if (!m_acl.empty()) {
-        static bool (IPRange::* contains)(const char*) const = &IPRange::contains;
-        if (find_if(m_acl.begin(), m_acl.end(), boost::bind(contains, _1, request.getRemoteAddr().c_str())) == m_acl.end()) {
+        auto contains = [&request](const IPRange& range) {
+            return range.contains(request.getRemoteAddr().c_str());
+        };
+
+        if (find_if(m_acl.begin(), m_acl.end(), contains) == m_acl.end()) {
             request.log(Priority::SHIB_WARN, string("handler request blocked from invalid address (") + request.getRemoteAddr() + ')');
             istringstream msg("Access Denied");
             return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_FORBIDDEN));
diff --git a/shibsp/handler/impl/SessionHandler.cpp b/shibsp/handler/impl/SessionHandler.cpp
index a84bd648..dddede3f 100644
--- a/shibsp/handler/impl/SessionHandler.cpp
+++ b/shibsp/handler/impl/SessionHandler.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * SessionHandler.cpp
+ * handler/impl/SessionHandler.cpp
  *
  * Handler for dumping information about an active session.
  */
@@ -29,6 +23,7 @@
 #include "SPRequest.h"
 #include "attribute/Attribute.h"
 #include "handler/SecuredHandler.h"
+#include "logging/Category.h"
 #include "session/SessionCache.h"
 #include "util/Date.h"
 
@@ -36,8 +31,7 @@
 #include <sstream>
 
 using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
+using namespace boost::property_tree;
 using namespace std;
 
 namespace shibsp {
@@ -50,7 +44,7 @@ namespace shibsp {
     class SHIBSP_API SessionHandler : public SecuredHandler
     {
     public:
-        SessionHandler(const DOMElement* e, const char* appId);
+        SessionHandler(const ptree& pt);
         virtual ~SessionHandler() {}
 
         pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
@@ -67,25 +61,21 @@ namespace shibsp {
     #pragma warning( pop )
 #endif
 
-    Handler* SHIBSP_DLLLOCAL SessionHandlerFactory(const pair<const DOMElement*,const char*>& p, bool)
+    Handler* SHIBSP_DLLLOCAL SessionHandlerFactory(const pair<ptree&,const char*>& p, bool)
     {
-        return new SessionHandler(p.first, p.second);
+        return new SessionHandler(p.first);
     }
 
 };
 
-SessionHandler::SessionHandler(const DOMElement* e, const char* appId)
-    : SecuredHandler(e, Category::getInstance(SHIBSP_LOGCAT ".Handler.Session")), m_values(false)
+SessionHandler::SessionHandler(const ptree& pt)
+    : SecuredHandler(pt, Category::getInstance(SHIBSP_LOGCAT ".Handler.Session")), m_values(false)
 {
-    pair<bool,const char*> prop = getString("contentType");
-    if (prop.first)
-        m_contentType = prop.second;
+    m_contentType = getString("contentType", "");
     if (!m_contentType.empty() && m_contentType != "application/json" && m_contentType != "text/html")
         throw ConfigurationException("Unsupported contentType property in Session Handler configuration.");
 
-    pair<bool,bool> flag = getBool("showAttributeValues");
-    if (flag.first)
-        m_values = flag.second;
+    m_values = getBool("showAttributeValues", false);
 }
 
 namespace {
@@ -129,8 +119,10 @@ pair<bool,long> SessionHandler::run(SPRequest& request, bool isHandler) const
     pair<bool,long> ret = SecuredHandler::run(request, isHandler);
     if (ret.first)
         return ret;
+
     request.setResponseHeader("Expires","Wed, 01 Jan 1997 12:00:00 GMT");
     request.setResponseHeader("Cache-Control","private,no-store,no-cache,max-age=0");
+
     if (m_contentType == "application/json") {
         request.setContentType(m_contentType.c_str());
         return doJSON(request);
@@ -151,7 +143,7 @@ pair<bool,long> SessionHandler::doJSON(SPRequest& request) const
             return make_pair(true, request.sendResponse(s));
         }
     }
-    catch (std::exception& ex) {
+    catch (exception& ex) {
         m_log.info("exception accessing user session: %s", ex.what());
         s << "{}" << endl;
         return make_pair(true, request.sendError(s));
@@ -268,7 +260,7 @@ pair<bool,long> SessionHandler::doHTML(SPRequest& request) const
             return make_pair(true, request.sendResponse(s));
         }
     }
-    catch (std::exception& ex) {
+    catch (exception& ex) {
         s << "Exception while retrieving active session:" << endl
             << '\t' << ex.what() << "</pre></body></html>" << endl;
         return make_pair(true, request.sendResponse(s));
diff --git a/shibsp/handler/impl/SessionInitiator.cpp b/shibsp/handler/impl/SessionInitiator.cpp
index 1f7aef63..fa98e765 100644
--- a/shibsp/handler/impl/SessionInitiator.cpp
+++ b/shibsp/handler/impl/SessionInitiator.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * SessionInitiator.cpp
+ * handler/impl/SessionInitiator.cpp
  * 
  * Pluggable runtime functionality that handles initiating sessions.
  */
@@ -28,12 +22,14 @@
 #include "exceptions.h"
 #include "SPRequest.h"
 #include "handler/SessionInitiator.h"
+#include "logging/Category.h"
+#include "util/Misc.h"
 
 using namespace shibsp;
-using namespace xercesc;
+using namespace boost::property_tree;
 using namespace std;
 
-SessionInitiator::SessionInitiator()
+SessionInitiator::SessionInitiator(const ptree& pt, Category& log) : AbstractHandler(pt, log)
 {
 }
 
@@ -41,16 +37,6 @@ SessionInitiator::~SessionInitiator()
 {
 }
 
-const char* SessionInitiator::remap(const char* src, Category& log) const
-{
-    if (XMLString::equals(src, "defaultACSIndex")) {
-        return "acsIndex";
-    }
-    else {
-        return src;
-    }
-}
-
 const set<string>& SessionInitiator::getSupportedOptions() const
 {
     return m_supportedOptions;
@@ -62,31 +48,25 @@ bool SessionInitiator::checkCompatibility(SPRequest& request, bool isHandler) co
     if (isHandler) {
         const char* flag = request.getParameter("isPassive");
         if (flag) {
-            isPassive = (*flag=='1' || *flag=='t');
+            string_to_bool_translator tr;
+            boost::optional<bool> b = tr.get_value(flag);
+            isPassive = b.has_value() ? b.get() : false;
         }
         else {
-            pair<bool,bool> flagprop = getBool("isPassive");
-            isPassive = (flagprop.first && flagprop.second);
+            isPassive = getBool("isPassive", false);
         }
     }
     else {
         // It doesn't really make sense to use isPassive with automated sessions, but...
-        pair<bool,bool> flagprop;
         if (request.getRequestSettings().first->hasProperty("isPassive")) {
-            flagprop.second = request.getRequestSettings().first->getBool("isPassive", false);
-            flagprop.first = true;
+            isPassive = request.getRequestSettings().first->getBool("isPassive", false);
+        } else {
+            isPassive = getBool("isPassive", false);
         }
-        if (!flagprop.first)
-            flagprop = getBool("isPassive");
-        isPassive = (flagprop.first && flagprop.second);
     }
 
     // Check for support of isPassive if it's used.
     if (isPassive && getSupportedOptions().count("isPassive") == 0) {
-        if (getParent()) {
-            log(Priority::SHIB_INFO, "handler does not support isPassive option");
-            return false;
-        }
         throw ConfigurationException("Unsupported option (isPassive) supplied to SessionInitiator.");
     }
 
@@ -95,6 +75,7 @@ bool SessionInitiator::checkCompatibility(SPRequest& request, bool isHandler) co
 
 pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
 {
+    /*
     cleanRelayState(request);
 
     const char* entityID = nullptr;
@@ -144,8 +125,8 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
 
             if (returnOnError) {
                 // Log it and attempt to recover relay state so we can get back.
-                log(Priority::SHIB_ERROR, ex.what());
-                log(Priority::SHIB_INFO, "trapping SessionInitiator error condition and returning to target location");
+                m_log.error(ex.what());
+                m_log.info("trapping SessionInitiator error condition and returning to target location");
                 flag = request.getParameter("target");
                 string target(flag ? flag : "");
                 recoverRelayState(request, target, false);
@@ -155,4 +136,5 @@ pair<bool,long> SessionInitiator::run(SPRequest& request, bool isHandler) const
         }
         throw;
     }
+    */
 }
diff --git a/shibsp/handler/impl/StatusHandler.cpp b/shibsp/handler/impl/StatusHandler.cpp
index 8e6f82e0..2117ac5e 100644
--- a/shibsp/handler/impl/StatusHandler.cpp
+++ b/shibsp/handler/impl/StatusHandler.cpp
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
@@ -30,25 +24,25 @@
 #include "SPRequest.h"
 #include "handler/RemotedHandler.h"
 #include "handler/SecuredHandler.h"
+#include "logging/Category.h"
+#include "session/SessionCache.h"
 #include "util/CGIParser.h"
+#include "util/Date.h"
 #include "util/Misc.h"
 
 #include <sstream>
 
-#include <boost/iterator/indirect_iterator.hpp>
-#include <boost/scoped_ptr.hpp>
-#include <xmltooling/version.h>
-#include <xercesc/util/XMLDateTime.hpp>
-
 #ifdef HAVE_SYS_UTSNAME_H
 # include <sys/utsname.h>
 #endif
 
 using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
+using namespace boost::property_tree;
 using namespace std;
 
+#ifndef HAVE_STRCASECMP
+# define strncasecmp _strnicmp
+#endif
 namespace shibsp {
 
 #if defined (_MSC_VER)
@@ -56,17 +50,15 @@ namespace shibsp {
     #pragma warning( disable : 4250 )
 #endif
 
-    class SHIBSP_API StatusHandler : public SecuredHandler, public RemotedHandler
+    class SHIBSP_API StatusHandler : public SecuredHandler
     {
     public:
-        StatusHandler(const DOMElement* e, const char* appId);
+        StatusHandler(const ptree& pt);
         virtual ~StatusHandler() {}
 
         pair<bool,long> run(SPRequest& request, bool isHandler=true) const;
-        void receive(DDF& in, ostream& out);
 
     private:
-        pair<bool,long> processMessage(SPRequest& request) const;
         ostream& systemInfo(ostream& os) const;
     };
 
@@ -74,16 +66,15 @@ namespace shibsp {
     #pragma warning( pop )
 #endif
 
-    Handler* SHIBSP_DLLLOCAL StatusHandlerFactory(const pair<const DOMElement*,const char*>& p, bool)
+    Handler* SHIBSP_DLLLOCAL StatusHandlerFactory(const pair<ptree&,const char*>& p, bool)
     {
-        return new StatusHandler(p.first, p.second);
+        return new StatusHandler(p.first);
     }
 
     class DummyRequest : public HTTPRequest
     {
     public:
         DummyRequest(const char* url) : m_parser(nullptr), m_url(url), m_scheme(nullptr), m_query(nullptr), m_port(0) {
-#ifdef HAVE_STRCASECMP
             if (url && !strncasecmp(url,"http://", 7)) {
                 m_scheme = "http";
                 m_port = 80;
@@ -94,21 +85,9 @@ namespace shibsp {
                 m_port = 443;
                 url += 8;
             }
-            else
-#else
-            if (url && !strnicmp(url,"http://", 7)) {
-                m_scheme = "http";
-                m_port = 80;
-                url += 7;
-            }
-            else if (url && !strnicmp(url,"https://", 8)) {
-                m_scheme="https";
-                m_port = 443;
-                url += 8;
-            }
-            else
-#endif
+            else {
                 throw invalid_argument("Target parameter was not an absolute URL.");
+            }
 
             m_query = strchr(url,'?');
             if (m_query)
@@ -210,7 +189,7 @@ namespace shibsp {
         }
 
     private:
-        mutable boost::scoped_ptr<CGIParser> m_parser;
+        mutable unique_ptr<CGIParser> m_parser;
         const char* m_url;
         const char* m_scheme;
         const char* m_query;
@@ -219,12 +198,9 @@ namespace shibsp {
     };
 };
 
-StatusHandler::StatusHandler(const DOMElement* e, const char* appId)
-    : SecuredHandler(e, Category::getInstance(SHIBSP_LOGCAT ".Handler.Status"))
+StatusHandler::StatusHandler(const ptree& pt)
+    : SecuredHandler(pt, Category::getInstance(SHIBSP_LOGCAT ".Handler.Status"))
 {
-    string address(appId);
-    address += getString("Location").second;
-    setAddress(address.c_str());
 }
 
 pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
@@ -234,24 +210,21 @@ pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
     if (ret.first)
         return ret;
 
+    auto now = chrono::system_clock::now();
+
+    ostringstream ts;
+    ts << date::format("%FT%TZ", date::floor<chrono::milliseconds>(now));
+    string timestamp(ts.str());
+
     const char* target = request.getParameter("target");
     if (target) {
         // RequestMap query, so handle it inproc.
         DummyRequest dummy(target);
         RequestMapper::Settings settings = request.getAgent().getRequestMapper()->getSettings(dummy);
-        XMLDateTime now(time(nullptr), false);
-        now.parseDateTime();
-        auto_ptr_char timestamp(now.getFormattedString());
         request.setContentType("text/xml");
         stringstream msg;
-        msg << "<StatusHandler time='" << timestamp.get() << "'>";
-            msg << "<Version Xerces-C='" << XERCES_FULLVERSIONDOT
-                << "' XML-Tooling-C='" << gXMLToolingDotVersionStr
-#ifndef SHIBSP_LITE
-                << "' XML-Security-C='" << XSEC_FULLVERSIONDOT
-                << "' OpenSAML-C='" << gOpenSAMLDotVersionStr
-#endif
-                << "' Shibboleth='" << PACKAGE_VERSION << "'/>";
+        msg << "<StatusHandler time='" << timestamp << "'>";
+            msg << "<Version Shibboleth='" << PACKAGE_VERSION << "'/>";
             const char* setting = request.getParameter("setting");
                 systemInfo(msg) << "<RequestSettings";
                 if (setting) {
@@ -266,201 +239,41 @@ pair<bool,long> StatusHandler::run(SPRequest& request, bool isHandler) const
     }
 
     try {
-        if (false) {
-            // When out of process, we run natively and directly process the message.
-            return processMessage(request);
+        m_log.debug("processing status request");
+
+        stringstream s;
+        s << "<StatusHandler time='" << timestamp << "'>"
+            << "<Version Shibboleth='" << PACKAGE_VERSION << "'/>";
+        const char* status = "<OK/>";
+
+        systemInfo(s);
+
+        // General configuration and status report.
+        SessionCache* sc = request.getAgent().getSessionCache(false);
+        if (sc) {
+            s << "<SessionCache><OK/></SessionCache>";
         }
         else {
-            // When not out of process, we remote all the message processing.
-            DDF out,in = wrap(request);
-            DDFJanitor jin(in), jout(out);
-            out = send(request, in);
-            return unwrap(request, out);
+            s << "<SessionCache><None/></SessionCache>";
         }
-    }
-    catch (exception& ex) {
-        m_log.error("error while processing request: %s", ex.what());
-        XMLDateTime now(time(nullptr), false);
-        now.parseDateTime();
-        auto_ptr_char timestamp(now.getFormattedString());
+
+        s << "<Status>" << status << "</Status></StatusHandler>";
+
         request.setContentType("text/xml");
-        stringstream msg;
-        msg << "<StatusHandler time='" << timestamp.get() << "'>";
-            msg << "<Version Xerces-C='" << XERCES_FULLVERSIONDOT
-                << "' XML-Tooling-C='" << gXMLToolingDotVersionStr
-#ifndef SHIBSP_LITE
-                << "' XML-Security-C='" << XSEC_FULLVERSIONDOT
-                << "' OpenSAML-C='" << gOpenSAMLDotVersionStr
-#endif
-                << "' Shibboleth='" << PACKAGE_VERSION << "'/>";
-            systemInfo(msg) << "<Status><Exception>" << ex.what() << "</Exception></Status>";
-        msg << "</StatusHandler>";
-        return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
+        return make_pair(true, request.sendResponse(s));
     }
     catch (std::exception& ex) {
         m_log.error("error while processing request: %s", ex.what());
-        XMLDateTime now(time(nullptr), false);
-        now.parseDateTime();
-        auto_ptr_char timestamp(now.getFormattedString());
         request.setContentType("text/xml");
         stringstream msg;
-        msg << "<StatusHandler time='" << timestamp.get() << "'>";
-            msg << "<Version Xerces-C='" << XERCES_FULLVERSIONDOT
-                << "' XML-Tooling-C='" << gXMLToolingDotVersionStr
-#ifndef SHIBSP_LITE
-                << "' XML-Security-C='" << XSEC_FULLVERSIONDOT
-                << "' OpenSAML-C='" << gOpenSAMLDotVersionStr
-#endif
-                << "' Shibboleth='" << PACKAGE_VERSION << "'/>";
-            systemInfo(msg) << "<Status><Exception type='std::exception'>" << ex.what() << "</Exception></Status>";
-        msg << "</StatusHandler>";
+        msg << "<StatusHandler time='" << timestamp << "'>"
+            << "<Version Shibboleth='" << PACKAGE_VERSION << "'/>";
+        systemInfo(msg) << "<Status><Exception type='std::exception'>" << ex.what() << "</Exception></Status>"
+            << "</StatusHandler>";
         return make_pair(true, request.sendResponse(msg, HTTPResponse::SHIBSP_HTTP_STATUS_ERROR));
     }
 }
 
-void StatusHandler::receive(DDF& in, ostream& out)
-{
-    /*
-    // Find application.
-    const char* aid = in["application_id"].string();
-    const Application* app = aid ? SPConfig::getConfig().getServiceProvider()->getApplication(aid) : nullptr;
-    if (!app) {
-        // Something's horribly wrong.
-        m_log.error("couldn't find application (%s) for status request", aid ? aid : "(missing)");
-        throw ConfigurationException("Unable to locate application for status request, deleted?");
-    }
-
-    // Wrap a response shim.
-    DDF ret(nullptr);
-    DDFJanitor jout(ret);
-    boost::scoped_ptr<HTTPRequest> req(getRequest(*app, in));
-    boost::scoped_ptr<HTTPResponse> resp(getResponse(*app, ret));
-
-    // Since we're remoted, the result should either be a throw, a false/0 return,
-    // which we just return as an empty structure, or a response/redirect,
-    // which we capture in the facade and send back.
-    processMessage(*app, *req, *resp);
-    out << ret;
-    */
-}
-
-pair<bool,long> StatusHandler::processMessage(SPRequest& request) const
-{
-#ifndef SHIBSP_LITE
-    m_log.debug("processing status request");
-
-    XMLDateTime now(time(nullptr), false);
-    now.parseDateTime();
-    auto_ptr_char timestamp(now.getFormattedString());
-
-    stringstream s;
-    s << "<StatusHandler time='" << timestamp.get() << "'>";
-    const char* status = "<OK/>";
-
-    s << "<Version Xerces-C='" << XERCES_FULLVERSIONDOT
-        << "' XML-Tooling-C='" << gXMLToolingDotVersionStr
-        << "' XML-Security-C='" << XSEC_FULLVERSIONDOT
-        << "' OpenSAML-C='" << gOpenSAMLDotVersionStr
-        << "' Shibboleth='" << PACKAGE_VERSION << "'/>";
-
-    systemInfo(s);
-
-    const char* param = nullptr;
-    if (param) {
-    }
-    else {
-        // General configuration and status report.
-        try {
-            SessionCache* sc = application.getServiceProvider().getSessionCache(false);
-            if (sc) {
-                sc->test();
-                s << "<SessionCache><OK/></SessionCache>";
-            }
-            else {
-                s << "<SessionCache><None/></SessionCache>";
-            }
-        }
-        catch (XMLToolingException& ex) {
-            s << "<SessionCache><Exception type='" << ex.getClassName() << "'>" << ex.what() << "</Exception></SessionCache>";
-            status = "<Partial/>";
-        }
-        catch (std::exception& ex) {
-            s << "<SessionCache><Exception type='std::exception'>" << ex.what() << "</Exception></SessionCache>";
-            status = "<Partial/>";
-        }
-
-        MetadataProvider* m = application.getMetadataProvider(false);
-        Locker mlock(m);
-
-        const PropertySet* relyingParty = nullptr;
-        param=httpRequest.getParameter("entityID");
-        if (m && param)
-            relyingParty = application.getRelyingParty(m->getEntityDescriptor(MetadataProviderCriteria(application, param)).first);
-        else
-            relyingParty = &application;
-
-        s << "<Application id='" << application.getId() << "' entityID='" << relyingParty->getString("entityID").second << "'/>";
-
-        if (m)
-            m->outputStatus(s);
-
-        s << "<Handlers>";
-        vector<const Handler*> handlers;
-        application.getHandlers(handlers);
-        for (indirect_iterator<vector<const Handler*>::const_iterator> h = make_indirect_iterator(handlers.begin());
-                h != make_indirect_iterator(handlers.end()); ++h) {
-            s << "<Handler Location='" << h->getString("Location").second << "'";
-            if (h->getString("Binding").first)
-                s << " Binding='" << h->getString("Binding").second << "'";
-            s << "/>";
-        }
-        s << "</Handlers>";
-
-        CredentialResolver* credResolver = application.getCredentialResolver();
-        if (credResolver) {
-            Locker credLocker(credResolver);
-            CredentialCriteria cc;
-            cc.setUsage(Credential::SIGNING_CREDENTIAL);
-            pair<bool,const char*> keyName = relyingParty->getString("keyName");
-            if (keyName.first)
-                cc.getKeyNames().insert(keyName.second);
-            vector<const Credential*> creds;
-            credResolver->resolve(creds, &cc);
-            for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
-                KeyInfo* kinfo = (*c)->getKeyInfo();
-                if (kinfo) {
-                    scoped_ptr<KeyDescriptor> kd(KeyDescriptorBuilder::buildKeyDescriptor());
-                    kd->setUse(KeyDescriptor::KEYTYPE_SIGNING);
-                    kd->setKeyInfo(kinfo);
-                    s << *(kd.get());
-                }
-            }
-
-            cc.setUsage(Credential::ENCRYPTION_CREDENTIAL);
-            creds.clear();
-            cc.getKeyNames().clear();
-            credResolver->resolve(creds, &cc);
-            for (vector<const Credential*>::const_iterator c = creds.begin(); c != creds.end(); ++c) {
-                KeyInfo* kinfo = (*c)->getKeyInfo();
-                if (kinfo) {
-                    scoped_ptr<KeyDescriptor> kd(KeyDescriptorBuilder::buildKeyDescriptor());
-                    kd->setUse(KeyDescriptor::KEYTYPE_ENCRYPTION);
-                    kd->setKeyInfo(kinfo);
-                    s << *(kd.get());
-                }
-            }
-        }
-    }
-
-    s << "<Status>" << status << "</Status></StatusHandler>";
-
-    httpResponse.setContentType("text/xml");
-    return make_pair(true, httpResponse.sendResponse(s));
-#else
-    return make_pair(false, 0L);
-#endif
-}
-
 #ifdef WIN32
 typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
 typedef BOOL (WINAPI *PGVEA)(LPOSVERSIONINFOA);
diff --git a/shibsp/impl/AgentConfig.cpp b/shibsp/impl/AgentConfig.cpp
index 95535a1a..6e1695fc 100644
--- a/shibsp/impl/AgentConfig.cpp
+++ b/shibsp/impl/AgentConfig.cpp
@@ -26,6 +26,7 @@
 #include "Agent.h"
 #include "AgentConfig.h"
 #include "RequestMapper.h"
+#include "handler/Handler.h"
 #include "io/HTTPResponse.h"
 #include "logging/LoggingService.h"
 #include "remoting/RemotingService.h"
@@ -218,14 +219,12 @@ bool AgentInternalConfig::_init(const char* inst_prefix, const char* config_file
         XMLToolingConfig::getConfig().user_agent = string(PACKAGE_NAME) + '/' + PACKAGE_VERSION;
 
         registerAttributeFactories();
-        registerHandlers();
-        registerLogoutInitiators();
-        registerSessionInitiators();
         */
 
-        registerAgents();
+        registerHandlers();
         registerRemotingServices();
         registerSessionCaches();
+        registerAgents();
 
         /*
         // Yes, this isn't secure, will review where we do any random generation
@@ -290,8 +289,12 @@ void AgentInternalConfig::_term()
     Category& log=Category::getInstance(SHIBSP_LOGCAT ".AgentConfig");
     log.info("%s agent shutting down", PACKAGE_STRING);
 
-    AccessControlManager.deregisterFactories();
+    AgentManager.deregisterFactories();
+    SessionCacheManager.deregisterFactories();
+    RemotingServiceManager.deregisterFactories();
+    HandlerManager.deregisterFactories();
     RequestMapperManager.deregisterFactories();
+    AccessControlManager.deregisterFactories();
     LoggingServiceManager.deregisterFactories();
 
     for (vector<void*>::reverse_iterator i=m_libhandles.rbegin(); i!=m_libhandles.rend(); i++) {
@@ -316,14 +319,8 @@ void AgentInternalConfig::_term()
     m_logging->term();
 
     /*
-    LogoutInitiatorManager.deregisterFactories();
-    SessionInitiatorManager.deregisterFactories();
-    HandlerManager.deregisterFactories();
     */
 
-    AgentManager.deregisterFactories();
-    RemotingServiceManager.deregisterFactories();
-    SessionCacheManager.deregisterFactories();
 
     /*
     Attribute::deregisterFactories();
diff --git a/shibsp/paths.h.in b/shibsp/paths.h.in
index b72cdbdb..a2b3d9b0 100644
--- a/shibsp/paths.h.in
+++ b/shibsp/paths.h.in
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/resource.h b/shibsp/resource.h
index 9b2726a9..fb280f2f 100644
--- a/shibsp/resource.h
+++ b/shibsp/resource.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 //{{NO_DEPENDENCIES}}
diff --git a/shibsp/util/BoostPropertySet.cpp b/shibsp/util/BoostPropertySet.cpp
index f24fdc83..4c394032 100644
--- a/shibsp/util/BoostPropertySet.cpp
+++ b/shibsp/util/BoostPropertySet.cpp
@@ -38,14 +38,6 @@ PropertySet::~PropertySet()
 {
 }
 
-PropertySet2::PropertySet2()
-{
-}
-
-PropertySet2::~PropertySet2()
-{
-}
-
 BoostPropertySet::BoostPropertySet() : m_parent(nullptr), m_pt(nullptr)
 {
 }
@@ -54,12 +46,12 @@ BoostPropertySet::~BoostPropertySet()
 {
 }
 
-const PropertySet2* BoostPropertySet::getParent() const
+const PropertySet* BoostPropertySet::getParent() const
 {
     return m_parent;
 }
 
-void BoostPropertySet::setParent(const PropertySet2* parent)
+void BoostPropertySet::setParent(const PropertySet* parent)
 {
     m_parent = parent;
 }
diff --git a/shibsp/util/BoostPropertySet.h b/shibsp/util/BoostPropertySet.h
index c82fb31a..068bde6c 100644
--- a/shibsp/util/BoostPropertySet.h
+++ b/shibsp/util/BoostPropertySet.h
@@ -43,7 +43,7 @@ namespace shibsp {
      * names for attributes and element content and can therefore not be used
      * directly as a means of exposing the properties via this interface.</p>
      */
-    class SHIBSP_API BoostPropertySet : public virtual PropertySet2
+    class SHIBSP_API BoostPropertySet : public virtual PropertySet
     {
     public:
         BoostPropertySet();
@@ -69,17 +69,17 @@ namespace shibsp {
          * 
          * @return parent PropertySet
          */
-        const PropertySet2* getParent() const;
+        const PropertySet* getParent() const;
 
         /**
          * Installs a parent PropertySet to allow an inheritance relationship to a different instance.
          * 
          * @param parent the parent PropertySet to install
          */
-        void setParent(const PropertySet2* parent);
+        void setParent(const PropertySet* parent);
 
     private:
-        const PropertySet2* m_parent;
+        const PropertySet* m_parent;
         const boost::property_tree::ptree* m_pt;
 		std::set<std::string> m_unset;
     };
diff --git a/shibsp/util/CGIParser.cpp b/shibsp/util/CGIParser.cpp
index c351e355..abadcd4a 100644
--- a/shibsp/util/CGIParser.cpp
+++ b/shibsp/util/CGIParser.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * CGIParser.cpp
+ * util/CGIParser.cpp
  * 
  * CGI GET/POST parameter parsing.
  */
diff --git a/shibsp/util/CGIParser.h b/shibsp/util/CGIParser.h
index 7dd3036f..ad40642b 100644
--- a/shibsp/util/CGIParser.h
+++ b/shibsp/util/CGIParser.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/util/DOMPropertySet.cpp b/shibsp/util/DOMPropertySet.cpp
deleted file mode 100644
index e5c330ed..00000000
--- a/shibsp/util/DOMPropertySet.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/**
- * 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.
- *
- * 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
- *
- * 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.
- */
-
-/**
- * DOMPropertySet.cpp
- * 
- * DOM-based property set implementation.
- */
-
-#include "internal.h"
-
-#include "AgentConfig.h"
-#include "logging/Category.h"
-#include "util/DOMPropertySet.h"
-#include "util/SPConstants.h"
-
-#include <algorithm>
-#include <boost/lexical_cast.hpp>
-#include <boost/algorithm/string.hpp>
-#include <xmltooling/QName.h>
-#include <xmltooling/util/XMLConstants.h>
-#include <xmltooling/util/XMLHelper.h>
-
-using namespace shibsp;
-using namespace xmltooling;
-using namespace xercesc;
-using namespace boost;
-using namespace std;
-
-DOMPropertySet::Remapper::Remapper()
-{
-}
-
-DOMPropertySet::Remapper::~Remapper()
-{
-}
-
-DOMPropertySet::STLRemapper::STLRemapper(const std::map<std::string, std::string>& rules) : m_rules(rules)
-{
-}
-
-DOMPropertySet::STLRemapper::~STLRemapper()
-{
-}
-
-const char* DOMPropertySet::STLRemapper::remap(const char* src, Category& log) const
-{
-    map<string,string>::const_iterator i = src ? m_rules.find(src) : m_rules.end();
-    if (i != m_rules.end()) {
-        AgentConfig::getConfig().deprecation().warn("legacy configuration, remapping property/set (%s) to (%s)", src, i->second.c_str());
-        return i->second.c_str();
-    }
-    else {
-        return src;
-    }
-}
-
-DOMPropertySet::DOMPropertySet() : m_parent(nullptr), m_root(nullptr)
-{
-}
-
-DOMPropertySet::~DOMPropertySet()
-{
-    for (map<string,pair<char*,const XMLCh*> >::iterator i = m_map.begin(); i != m_map.end(); ++i)
-        XMLString::release(&(i->second.first));
-}
-
-const PropertySet* DOMPropertySet::getParent() const
-{
-    return m_parent;
-}
-
-void DOMPropertySet::setParent(const PropertySet* parent)
-{
-    m_parent = parent;
-}
-
-void DOMPropertySet::load(
-    const DOMElement* e,
-    Category* log,
-    DOMNodeFilter* filter,
-    const Remapper* remapper,
-    const xmltooling::QName* unsetter
-    )
-{
-    if (!e)
-        return;
-    m_root=e;
-    if (!log)
-        log = &Category::getInstance(SHIBSP_LOGCAT ".PropertySet");
-
-    // Process each attribute as a property.
-    DOMNamedNodeMap* attrs=m_root->getAttributes();
-    for (XMLSize_t i=0; i<attrs->getLength(); i++) {
-        DOMNode* a=attrs->item(i);
-        if (!XMLString::compareString(a->getNamespaceURI(), xmlconstants::XMLNS_NS)) {
-            continue;
-        }
-        else if (unsetter && XMLHelper::isNodeNamed(a, unsetter->getNamespaceURI(), unsetter->getLocalPart())) {
-            auto_ptr_char val(a->getNodeValue());
-            string dup(val.get());
-            split(m_unset, dup, is_space(), algorithm::token_compress_on);
-            continue;
-        }
-
-        char* val=XMLString::transcode(a->getNodeValue());
-        if (val && *val) {
-            auto_ptr_char ns(a->getNamespaceURI());
-            auto_ptr_char name(a->getLocalName());
-            const char* realname=name.get();
-            if (remapper) {
-                realname = remapper->remap(realname, *log);
-            }
-            if (ns.get()) {
-                const char* realns = ns.get();
-                if (remapper) {
-                    realns = remapper->remap(realns, *log);
-                }
-                else if (XMLString::equals(realns, shibspconstants::ASCII_SHIB2SPCONFIG_NS)) {
-                    realns = shibspconstants::ASCII_SHIB3SPCONFIG_NS;
-                }
-                m_map[string("{") + realns + '}' + realname] = pair<char*, const XMLCh*>(val, a->getNodeValue());
-                log->debug("added property {%s}%s (%s)", realns, realname, val);
-            }
-            else {
-                m_map[realname]=pair<char*,const XMLCh*>(val,a->getNodeValue());
-                log->debug("added property %s (%s)", realname, val);
-            }
-        }
-    }
-    
-    // Process non-excluded elements as nested sets.
-    DOMTreeWalker* walker =
-        static_cast<DOMDocumentTraversal*>(
-            m_root->getOwnerDocument())->createTreeWalker(const_cast<DOMElement*>(m_root),DOMNodeFilter::SHOW_ELEMENT,filter,false
-            );
-    e = static_cast<DOMElement*>(walker->firstChild());
-    while (e) {
-        auto_ptr_char ns(e->getNamespaceURI());
-        auto_ptr_char name(e->getLocalName());
-        const char* realname=name.get();
-        if (remapper) {
-            realname = remapper->remap(realname, *log);
-        }
-        string key;
-        if (ns.get()) {
-            const char* realns = ns.get();
-            if (remapper) {
-                realns = remapper->remap(realns, *log);
-            }
-            else if (XMLString::equals(realns, shibspconstants::ASCII_SHIB2SPCONFIG_NS)) {
-                realns = shibspconstants::ASCII_SHIB3SPCONFIG_NS;
-            }
-            key = string("{") + realns + '}' + realname;
-        }
-        else {
-            key = realname;
-        }
-        if (m_nested.find(key) != m_nested.end())
-            log->warn("load() skipping duplicate property set: %s", key.c_str());
-        else {
-            boost::shared_ptr<DOMPropertySet> newset(new DOMPropertySet());
-            newset->load(e,log,filter,remapper);
-            m_nested[key] = newset;
-            log->debug("added nested property set: %s", key.c_str());
-        }
-        e = static_cast<DOMElement*>(walker->nextSibling());
-    }
-    walker->release();
-}
-
-pair<bool,bool> DOMPropertySet::getBool(const char* name) const
-{
-    const auto i = m_map.find(name);
-    if (i!=m_map.end())
-        return make_pair(true,(!strcmp(i->second.first,"true") || !strcmp(i->second.first,"1")));
-    else if (m_parent && m_unset.find(name) == m_unset.end()) {
-        return m_parent->getBool(name);
-    }
-    return make_pair(false,false);
-}
-
-pair<bool,const char*> DOMPropertySet::getString(const char* name) const
-{
-    const auto i = m_map.find(name);
-    if (i!=m_map.end())
-        return pair<bool,const char*>(true,i->second.first);
-    else if (m_parent && m_unset.find(name) == m_unset.end())
-        return m_parent->getString(name);
-    return pair<bool,const char*>(false,nullptr);
-}
-
-pair<bool,unsigned int> DOMPropertySet::getUnsignedInt(const char* name) const
-{
-    const auto i = m_map.find(name);
-    if (i!=m_map.end()) {
-        try {
-            return pair<bool,unsigned int>(true,lexical_cast<unsigned int>(i->second.first));
-        }
-        catch (bad_lexical_cast&) {
-            return pair<bool,unsigned int>(false,0);
-        }
-    }
-    else if (m_parent && m_unset.find(name) == m_unset.end())
-        return m_parent->getUnsignedInt(name);
-    return pair<bool,unsigned int>(false,0);
-}
-
-pair<bool,int> DOMPropertySet::getInt(const char* name) const
-{
-    const auto i = m_map.find(name);
-    if (i!=m_map.end())
-        return pair<bool,int>(true,atoi(i->second.first));
-    else if (m_parent && m_unset.find(name) == m_unset.end())
-        return m_parent->getInt(name);
-    return pair<bool,int>(false,0);
-}
-
-const PropertySet* DOMPropertySet::getPropertySet(const char* name) const
-{
-    const auto i = m_nested.find(name);
-
-    return (i != m_nested.end()) ? i->second.get() : (m_parent ? m_parent->getPropertySet(name) : nullptr);
-}
-
-bool DOMPropertySet::setProperty(const char* name, const char* val)
-{
-    // Erase existing property.
-    if (m_map.count(name) > 0) {
-        XMLString::release(&m_map[name].first);
-        m_map.erase(name);
-    }
-
-    char* dup = XMLString::replicate(val);
-    auto_ptr_XMLCh widedup(val);
-    m_injected.push_back(widedup.get());
-    m_map[name] = make_pair(dup, m_injected.back().c_str());
-
-    return true;
-}
diff --git a/shibsp/util/DOMPropertySet.h b/shibsp/util/DOMPropertySet.h
deleted file mode 100644
index 62ab9d60..00000000
--- a/shibsp/util/DOMPropertySet.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * 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.
- *
- * 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
- *
- * 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.
- */
-
-/**
- * @file shibsp/util/DOMPropertySet.h
- * 
- * DOM-based property set implementation.
- */
-
-#ifndef __shibsp_dompropset_h__
-#define __shibsp_dompropset_h__
-
-#include <shibsp/util/PropertySet.h>
-#include <xmltooling/unicode.h>
-
-#include <set>
-#include <boost/shared_ptr.hpp>
-#include <xercesc/dom/DOM.hpp>
-
-#if defined (_MSC_VER)
-#    pragma warning( push )
-#    pragma warning( disable : 4251 )
-#endif
-
-namespace xmltooling {
-	class QName;
-}
-
-namespace shibsp {
-
-    class SHIBSP_API Category;
-
-    /**
-     * DOM-based property set implementation.
-     */
-    class SHIBSP_API DOMPropertySet : public virtual PropertySet
-    {
-    public:
-        DOMPropertySet();
-        
-        virtual ~DOMPropertySet();
-
-        const PropertySet* getParent() const;
-        void setParent(const PropertySet* parent);
-        std::pair<bool,bool> getBool(const char* name) const;
-        std::pair<bool,const char*> getString(const char* name) const;
-        std::pair<bool,unsigned int> getUnsignedInt(const char* name) const;
-        std::pair<bool,int> getInt(const char* name) const;
-        const PropertySet* getPropertySet(const char* name) const;
-
-        /**
-         * Interface that remaps property names for legacy support.
-         */
-        class SHIBSP_API Remapper {
-            MAKE_NONCOPYABLE(Remapper);
-        protected:
-            /** Constructor. */
-            Remapper();
-
-        public:
-            /** Destructor. */
-            virtual ~Remapper();
-
-            /**
-             * Remap a name (or return it unchanged).
-             *
-             * @param src original name
-             * @param log logger to use
-             *
-             * @return the name to use
-             */
-            virtual const char* remap(const char* src, Category& log) const=0;
-        };
-
-        /**
-         * Concrete remapper that relies on an STL map.
-         */
-        class SHIBSP_API STLRemapper : public Remapper {
-        public:
-            /**
-             * Constructor.
-             *
-             * @param rules remapping rules
-             */
-            STLRemapper(const std::map<std::string,std::string>& rules);
-            virtual ~STLRemapper();
-
-            const char* remap(const char* src, Category& log) const;
-
-        private:
-            const std::map<std::string, std::string>& m_rules;
-        };
-
-        /**
-         * Loads the property set from a DOM element.
-         * 
-         * @param e         root element of property set
-         * @param log       optional log object for tracing
-         * @param filter    optional filter controls what child elements to include as nested PropertySets
-         * @param remapper  optional mapper of property rename rules for legacy property support
-		 * @param unsetter  optional name of a property containing a list of property names to "unset"
-         */
-        void load(
-            const xercesc::DOMElement* e,
-            Category* log=nullptr,
-            xercesc::DOMNodeFilter* filter=nullptr,
-            const Remapper* remapper=nullptr,
-			const xmltooling::QName* unsetter=nullptr
-            );
-
-    protected:
-        /**
-         * Post-load injection of a property, for use by subclasses.
-         *
-         * @param name  property name
-         * @param val   property value
-         * @param ns    property namespace
-         * @return  true iff the property was successfully set
-         */
-        bool setProperty(const char* name, const char* val);
-
-    private:
-        const PropertySet* m_parent;
-        const xercesc::DOMElement* m_root;
-        std::map<std::string,std::pair<char*,const XMLCh*> > m_map;
-		std::set<std::string> m_unset;
-        std::map< std::string,boost::shared_ptr<DOMPropertySet> > m_nested;
-        std::vector<xmltooling::xstring> m_injected;
-    };
-
-};
-
-#if defined (_MSC_VER)
-#   pragma warning( pop )
-#endif
-
-#endif /* __shibsp_dompropset_h__ */
diff --git a/shibsp/util/IPRange.cpp b/shibsp/util/IPRange.cpp
index 2cf829cb..354010d5 100644
--- a/shibsp/util/IPRange.cpp
+++ b/shibsp/util/IPRange.cpp
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/util/IPRange.h b/shibsp/util/IPRange.h
index 84c0f19c..8beb3287 100644
--- a/shibsp/util/IPRange.h
+++ b/shibsp/util/IPRange.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/util/PathResolver.cpp b/shibsp/util/PathResolver.cpp
index 47324c33..6663b7a1 100644
--- a/shibsp/util/PathResolver.cpp
+++ b/shibsp/util/PathResolver.cpp
@@ -1,25 +1,19 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * PathResolver.cpp
+ * util/PathResolver.cpp
  *
  * Resolves local filenames into absolute pathnames.
  */
diff --git a/shibsp/util/PropertySet.h b/shibsp/util/PropertySet.h
index a405bb8b..7627d787 100644
--- a/shibsp/util/PropertySet.h
+++ b/shibsp/util/PropertySet.h
@@ -38,84 +38,6 @@ namespace shibsp {
     public:
         virtual ~PropertySet();
 
-        /**
-         * Returns parent of this PropertySet, if any.
-         *
-         * @return the parent object, or nullptr
-         */
-        virtual const PropertySet* getParent() const=0;
-
-        /**
-         * Establishes a "parent" PropertySet to supply inherited settings.
-         *
-         * @param parent    the parent PropertySet to use
-         */
-        virtual void setParent(const PropertySet* parent)=0;
-
-        /**
-         * Returns a boolean-valued property.
-         * 
-         * @param name  property name
-         * @param ns    property namespace, or nullptr
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
-         */
-        virtual std::pair<bool,bool> getBool(const char* name) const=0;
-
-        /**
-         * Returns a string-valued property.
-         * 
-         * @param name  property name
-         * @param ns    property namespace, or nullptr
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
-         */
-        virtual std::pair<bool,const char*> getString(const char* name) const=0;
-
-        /**
-         * Returns an unsigned integer-valued property.
-         * 
-         * @param name  property name
-         * @param ns    property namespace, or nullptr
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
-         */
-        virtual std::pair<bool,unsigned int> getUnsignedInt(const char* name) const=0;
-
-        /**
-         * Returns an integer-valued property.
-         * 
-         * @param name  property name
-         * @param ns    property namespace, or nullptr
-         * @return a pair consisting of a nullptr indicator and the property value iff the indicator is true
-         */
-        virtual std::pair<bool,int> getInt(const char* name) const=0;
-
-        /**
-         * Returns a nested property set.
-         * 
-         * @param name  nested property set name
-         * @param ns    nested property set namespace, or nullptr
-         * @return the nested property set, or nullptr
-         */        
-        virtual const PropertySet* getPropertySet(const char* name) const=0;
-    };
-
-    /**
-     * Interface to a generic set of typed properties.
-     * 
-     * <p>This new variant will be based on supporting a dotted path syntax to access
-     * "nested" sets of named properties, which used to be navigated explicitly with
-     * a hierarchy of child objects. That is now only one-way, down the tree.</p>
-     * 
-     * TODO: This will replace the original interface and be renamed back to PropertySet
-     * once code migration is completed.
-     */
-    class SHIBSP_API PropertySet2
-    {
-        MAKE_NONCOPYABLE(PropertySet2);
-    protected:
-        PropertySet2();
-    public:
-        virtual ~PropertySet2();
-
         /**
          * Gets whether a matching property exists.
          * 
diff --git a/shibsp/util/SPConstants.cpp b/shibsp/util/SPConstants.cpp
index ce21cc79..e60e4f32 100644
--- a/shibsp/util/SPConstants.cpp
+++ b/shibsp/util/SPConstants.cpp
@@ -1,114 +1,26 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
- * SPConstants.cpp
+ * util/SPConstants.cpp
  * 
  * Shibboleth SP XML constants.
  */
 
 #include "internal.h"
 #include "util/SPConstants.h"
-#include <xercesc/util/XMLUniDefs.hpp>
 
 using namespace shibspconstants;
-using namespace xercesc;
-
-const XMLCh shibspconstants::SHIB1_PROTOCOL_ENUM[] = // urn:mace:shibboleth:1.0
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chDigit_1, chPeriod, chDigit_0, chNull
-};
-
-const XMLCh shibspconstants::SHIBMD_NS[] = // urn:mace:shibboleth:metadata:1.0
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chLatin_m, chLatin_e, chLatin_t, chLatin_a, chLatin_d, chLatin_a, chLatin_t, chLatin_a, chColon,
-  chDigit_1, chPeriod, chDigit_0, chNull
-};
-
-const XMLCh shibspconstants::SHIBMD_PREFIX[] = UNICODE_LITERAL_6(s,h,i,b,m,d);
-
-const XMLCh shibspconstants::SHIB3SPCONFIG_NS[] = // urn:mace:shibboleth:3.0:native:sp:config
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-chDigit_3, chPeriod, chDigit_0, chColon, chLatin_n, chLatin_a, chLatin_t, chLatin_i, chLatin_v, chLatin_e, chColon,
-chLatin_s, chLatin_p, chColon, chLatin_c, chLatin_o, chLatin_n, chLatin_f, chLatin_i, chLatin_g, chNull
-};
-
-const XMLCh shibspconstants::SHIB2SPCONFIG_NS[] = // urn:mace:shibboleth:2.0:native:sp:config
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chDigit_2, chPeriod, chDigit_0, chColon, chLatin_n, chLatin_a, chLatin_t, chLatin_i, chLatin_v, chLatin_e, chColon,
-  chLatin_s, chLatin_p, chColon, chLatin_c, chLatin_o, chLatin_n, chLatin_f, chLatin_i, chLatin_g, chNull
-};
-
-const XMLCh* shibspconstants::SHIBSPCONFIG_NS = shibspconstants::SHIB3SPCONFIG_NS;
-
-const XMLCh shibspconstants::SHIB2SPNOTIFY_NS[] = // urn:mace:shibboleth:2.0:sp:notify
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chDigit_2, chPeriod, chDigit_0, chColon, chLatin_s, chLatin_p, chColon,
-  chLatin_n, chLatin_o, chLatin_t, chLatin_i, chLatin_f, chLatin_y, chNull
-};
-
-const XMLCh shibspconstants::SHIB1_ATTRIBUTE_NAMESPACE_URI[] = // urn:mace:shibboleth:1.0:attributeNamespace:uri
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chDigit_1, chPeriod, chDigit_0, chColon,
-  chLatin_a, chLatin_t, chLatin_t, chLatin_r, chLatin_i, chLatin_b, chLatin_u, chLatin_t, chLatin_e,
-    chLatin_N, chLatin_a, chLatin_m, chLatin_e, chLatin_s, chLatin_p, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_u, chLatin_r, chLatin_i, chNull
-};
-
-const XMLCh shibspconstants::SHIB1_NAMEID_FORMAT_URI[] = // urn:mace:shibboleth:1.0:nameIdentifier
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chDigit_1, chPeriod, chDigit_0, chColon,
-  chLatin_n, chLatin_a, chLatin_m, chLatin_e,
-    chLatin_I, chLatin_d, chLatin_e, chLatin_n, chLatin_t, chLatin_i, chLatin_f, chLatin_i, chLatin_e, chLatin_r, chNull
-};
-
-const XMLCh shibspconstants::SHIB1_AUTHNREQUEST_PROFILE_URI[] = // urn:mace:shibboleth:1.0:profiles:AuthnRequest
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chDigit_1, chPeriod, chDigit_0, chColon,
-  chLatin_p, chLatin_r, chLatin_o, chLatin_f, chLatin_i, chLatin_l, chLatin_e, chLatin_s, chColon,
-  chLatin_A, chLatin_u, chLatin_t, chLatin_h, chLatin_n,
-  chLatin_R, chLatin_e, chLatin_q, chLatin_u, chLatin_e, chLatin_s, chLatin_t, chNull
-};
-
-const XMLCh shibspconstants::SHIB2_BINDING_FILE[] = // urn:mace:shibboleth:2.0:bindings:File
-{ chLatin_u, chLatin_r, chLatin_n, chColon, chLatin_m, chLatin_a, chLatin_c, chLatin_e, chColon,
-  chLatin_s, chLatin_h, chLatin_i, chLatin_b, chLatin_b, chLatin_o, chLatin_l, chLatin_e, chLatin_t, chLatin_h, chColon,
-  chDigit_2, chPeriod, chDigit_0, chColon,
-  chLatin_b, chLatin_i, chLatin_n, chLatin_d, chLatin_i, chLatin_n, chLatin_g, chLatin_s, chColon,
-  chLatin_F, chLatin_i, chLatin_l, chLatin_e, chNull
-};
-
-const char shibspconstants::SHIB1_SESSIONINIT_PROFILE_URI[] = "urn:mace:shibboleth:sp:1.3:SessionInit";
-
-const char shibspconstants::SHIB1_LOGOUT_PROFILE_URI[] = "urn:mace:shibboleth:sp:1.3:Logout";
-
-const char shibspconstants::ASCII_SHIB3SPCONFIG_NS[] = "urn:mace:shibboleth:3.0:native:sp:config";
-
-const char shibspconstants::ASCII_SHIB2SPCONFIG_NS[] = "urn:mace:shibboleth:2.0:native:sp:config";
 
-const char* shibspconstants::ASCII_SHIBSPCONFIG_NS = shibspconstants::ASCII_SHIB3SPCONFIG_NS;
+const char shibspconstants::SHIB2SPNOTIFY_NS[] = "urn:mace:shibboleth:2.0:sp:notify";
diff --git a/shibsp/util/SPConstants.h b/shibsp/util/SPConstants.h
index 94e4d9ea..048ca6d9 100644
--- a/shibsp/util/SPConstants.h
+++ b/shibsp/util/SPConstants.h
@@ -35,53 +35,9 @@
  */
 namespace shibspconstants {
 
-    /**  Shibboleth Metadata XML namespace ("urn:mace:shibboleth:metadata:1.0") */
-    extern SHIBSP_API const XMLCh SHIBMD_NS[];
-
-    /** Shibboleth Metadata QName prefix ("shibmd") */
-    extern SHIBSP_API const XMLCh SHIBMD_PREFIX[];
-
-    /** "Current" Shibboleth SP configuration namespace */
-    extern SHIBSP_API const XMLCh* SHIBSPCONFIG_NS;
-
-    /** Shibboleth 3.0 SP configuration namespace ("urn:mace:shibboleth:3.0:native:sp:config") */
-    extern SHIBSP_API const XMLCh SHIB3SPCONFIG_NS[];
-
-    /** Shibboleth 2.0 SP configuration namespace ("urn:mace:shibboleth:2.0:native:sp:config") */
-    extern SHIBSP_API const XMLCh SHIB2SPCONFIG_NS[];
-
     /** Shibboleth 2.0 notification namespace ("urn:mace:shibboleth:2.0:sp:notify") */
-    extern SHIBSP_API const XMLCh SHIB2SPNOTIFY_NS[];
-
-    /** Shibboleth 1.x Protocol Enumeration constant ("urn:mace:shibboleth:1.0") */
-    extern SHIBSP_API const XMLCh SHIB1_PROTOCOL_ENUM[];
-
-    /** Shibboleth 1.x URI AttributeNamespace constant ("urn:mace:shibboleth:1.0:attributeNamespace:uri") */
-    extern SHIBSP_API const XMLCh SHIB1_ATTRIBUTE_NAMESPACE_URI[];
-
-    /** Shibboleth 1.x transient NameIdentifier Format constant ("urn:mace:shibboleth:1.0:nameIdentifier") */
-    extern SHIBSP_API const XMLCh SHIB1_NAMEID_FORMAT_URI[];
-
-    /** Shibboleth 1.x AuthnRequest binding/profile ("urn:mace:shibboleth:1.0:profiles:AuthnRequest") */
-    extern SHIBSP_API const XMLCh SHIB1_AUTHNREQUEST_PROFILE_URI[];
-
-    /** Shibboleth 2 filesystem-based SAML binding ("urn:mace:shibboleth:2.0:bindings:File") */
-    extern SHIBSP_API const XMLCh SHIB2_BINDING_FILE[];
-
-    /** Shibboleth 1.3 SessionInit binding/profile ("urn:mace:shibboleth:sp:1.3:SessionInit") */
-    extern SHIBSP_API const char SHIB1_SESSIONINIT_PROFILE_URI[];
-
-    /** Shibboleth 1.3 Local Logout binding/profile ("urn:mace:shibboleth:sp:1.3:Logout") */
-    extern SHIBSP_API const char SHIB1_LOGOUT_PROFILE_URI[];
-    
-    /** "Current" Shibboleth SP configuration namespace */
-    extern SHIBSP_API const char* ASCII_SHIBSPCONFIG_NS;
-
-    /** Shibboleth 3.0 SP configuration namespace ("urn:mace:shibboleth:3.0:native:sp:config") */
-    extern SHIBSP_API const char ASCII_SHIB3SPCONFIG_NS[];
+    extern SHIBSP_API const char SHIB2SPNOTIFY_NS[];
 
-    /** Shibboleth 2.0 SP configuration namespace ("urn:mace:shibboleth:2.0:native:sp:config") */
-    extern SHIBSP_API const char ASCII_SHIB2SPCONFIG_NS[];
 };
 
 #endif /* __shibsp_constants_h__ */
diff --git a/shibsp/version.cpp b/shibsp/version.cpp
index 0cacf619..c01a9287 100644
--- a/shibsp/version.cpp
+++ b/shibsp/version.cpp
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
diff --git a/shibsp/version.h b/shibsp/version.h
index cad520b2..1e66fe80 100644
--- a/shibsp/version.h
+++ b/shibsp/version.h
@@ -1,21 +1,15 @@
 /**
- * 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.
+ * 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
  *
- * 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
+ *    http://www.apache.org/licenses/LICENSE-2.0
  *
- * 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.
+ * 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.
  */
 
 /**
@@ -32,7 +26,6 @@
 // of this stuff, it can be copied into here.
 
 #include <shibsp/base.h>
-#include <xercesc/util/XercesVersion.hpp>
 
 // ---------------------------------------------------------------------------
 // V E R S I O N   S P E C I F I C A T I O N
@@ -48,6 +41,44 @@
 
 /** DO NOT MODIFY BELOW THIS LINE */
 
+// ---------------------------------------------------------------------------
+// T W O   A R G U M E N T   C O N C A T E N A T I O N   M A C R O S
+
+// two argument concatenation routines
+#define CAT2_SEP_UNDERSCORE(a, b) #a "_" #b
+#define CAT2_SEP_PERIOD(a, b) #a "." #b
+#define CAT2_SEP_NIL(a, b) #a #b
+#define CAT2_RAW_NUMERIC(a, b) a ## b
+
+// two argument macro invokers
+#define INVK_CAT2_SEP_UNDERSCORE(a,b) CAT2_SEP_UNDERSCORE(a,b)
+#define INVK_CAT2_SEP_PERIOD(a,b)     CAT2_SEP_PERIOD(a,b)
+#define INVK_CAT2_STR_SEP_NIL(a,b)    CAT2_SEP_NIL(a,b)
+#define INVK_CAT2_RAW_NUMERIC(a,b)    CAT2_RAW_NUMERIC(a,b)
+
+// ---------------------------------------------------------------------------
+// T H R E E   A R G U M E N T   C O N C A T E N A T I O N   M A C R O S
+
+// three argument concatenation routines
+#define CAT3_SEP_UNDERSCORE(a, b, c) #a "_" #b "_" #c
+#define CAT3_SEP_PERIOD(a, b, c) #a "." #b "." #c
+#define CAT3_SEP_NIL(a, b, c) #a #b #c
+#define CAT3_RAW_NUMERIC(a, b, c) a ## b ## c
+#define CAT3_RAW_NUMERIC_SEP_UNDERSCORE(a, b, c) a ## _ ## b ## _ ## c
+
+// three argument macro invokers
+#define INVK_CAT3_SEP_UNDERSCORE(a,b,c) CAT3_SEP_UNDERSCORE(a,b,c)
+#define INVK_CAT3_SEP_PERIOD(a,b,c)     CAT3_SEP_PERIOD(a,b,c)
+#define INVK_CAT3_SEP_NIL(a,b,c)        CAT3_SEP_NIL(a,b,c)
+#define INVK_CAT3_RAW_NUMERIC(a,b,c)    CAT3_RAW_NUMERIC(a,b,c)
+#define INVK_CAT3_RAW_NUMERIC_SEP_UNDERSCORE(a,b,c)    CAT3_RAW_NUMERIC_SEP_UNDERSCORE(a,b,c)
+
+// ---------------------------------------------------------------------------
+// C A L C U L A T E   V E R S I O N   -   E X P A N D E D   F O R M
+
+#define MULTIPLY(factor,value) factor * value
+#define CALC_EXPANDED_FORM(a,b,c) ( MULTIPLY(10000,a) + MULTIPLY(100,b) + MULTIPLY(1,c) )
+
 /**
  * MAGIC THAT AUTOMATICALLY GENERATES THE FOLLOWING:
  *
diff --git a/tests/util/BoostPropertySetTests.cpp b/tests/util/BoostPropertySetTests.cpp
index c3ab24f2..1abd07bd 100644
--- a/tests/util/BoostPropertySetTests.cpp
+++ b/tests/util/BoostPropertySetTests.cpp
@@ -62,7 +62,7 @@ public:
     TestBoostPropertySet() {} 
     virtual ~TestBoostPropertySet() {}
 
-    void setParent(const PropertySet2* parent) {
+    void setParent(const PropertySet* parent) {
         BoostPropertySet::setParent(parent);
     }
 };

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list