You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by bb...@apache.org on 2019/07/08 21:45:37 UTC

[geode-native] branch develop updated: GEODE-6914: Replace libxml with xerces-c in CacheXmlParser (#501)

This is an automated email from the ASF dual-hosted git repository.

bbender pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode-native.git


The following commit(s) were added to refs/heads/develop by this push:
     new b85c936  GEODE-6914: Replace libxml with xerces-c in CacheXmlParser (#501)
b85c936 is described below

commit b85c9366ccb055636f19922b96fbd4863e7b026f
Author: Blake Bender <bb...@pivotal.io>
AuthorDate: Mon Jul 8 14:45:33 2019 -0700

    GEODE-6914: Replace libxml with xerces-c in CacheXmlParser (#501)
    
    - Replaced libxml references with Xerces.
    - Removed dead code.
    - Add xerces-c project back into dependencies.  This was pulled in 11/2017, but we're switching to using it in product code now
    - Templatize function pointers using std::function
    - Remove unused endPdx method
    - Rename member variables to conform to our conventions
    - Move getFactoryFunc into Utils where it belongs
    - Added negative test case to verify we assert if missing required attribute
    - GEODE-6914: Apply correct compiler settings to Xerces
    - GEODE-6914: Disable schema validation for the time being
    - Add alias for xerces-c to CMakeLists, update reference to it
    - Mark Xerces headers as system headers
    - Spell out 'function' in getFactoryFunction
    - Corresponding formatting changes
    - Add a CacheXmlParser test that loads a cache.xml with a bad schema and assert it doesn't throw, i.e. we're not validating schemas
    
    Co-authored-by: Matthew Reddington <mr...@pivotal.io>
    Co-authored-by: Mike Martell <mm...@pivotal.io>
    Co-authored-by: Jacob Barrett <jb...@pivotal.io>
---
 FindNativeClientCPPCache.cmake                     |   32 -
 clicache/src/DistributedSystem.cpp                 |   10 +-
 cppcache/CMakeLists.txt                            |    2 +-
 cppcache/CPPCacheConfig.cmake                      |   14 -
 cppcache/FindCPPCache.cmake                        |   14 -
 cppcache/integration-test/resources/bad_schema.xml |   27 +
 cppcache/integration/framework/CMakeLists.txt      |   10 +-
 cppcache/integration/framework/Cluster.h           |   13 +-
 .../framework/{config.h.in => NamedType.h}         |   22 +-
 cppcache/integration/framework/TestConfig.cpp.in   |    1 +
 cppcache/integration/framework/TestConfig.h        |    2 +-
 cppcache/integration/test/CMakeLists.txt           |    1 +
 cppcache/integration/test/CacheXmlTest.cpp         |   77 +
 cppcache/src/CacheConfig.cpp                       |  138 --
 cppcache/src/CacheConfig.hpp                       |   77 -
 cppcache/src/CacheFactory.cpp                      |    1 -
 cppcache/src/CacheXml.cpp                          |  192 ---
 cppcache/src/CacheXml.hpp                          |  220 ---
 cppcache/src/CacheXmlParser.cpp                    | 1787 +++++++++-----------
 cppcache/src/CacheXmlParser.hpp                    |  170 +-
 cppcache/src/RegionAttributes.cpp                  |   73 +-
 cppcache/src/RegionFactory.cpp                     |    1 -
 cppcache/src/ThinClientPoolDM.cpp                  |    8 +-
 cppcache/src/Utils.cpp                             |   15 +
 cppcache/src/Utils.hpp                             |   10 +
 cppcache/test/CacheXmlParserTest.cpp               |   91 +-
 dependencies/CMakeLists.txt                        |    2 +-
 dependencies/libxml2/CMakeLists.txt                |   91 -
 dependencies/xerces-c/CMakeLists.txt               |   65 +
 dist/LICENSE                                       |   27 -
 30 files changed, 1209 insertions(+), 1984 deletions(-)

diff --git a/FindNativeClientCPPCache.cmake b/FindNativeClientCPPCache.cmake
index 6ea6143..697cd18 100644
--- a/FindNativeClientCPPCache.cmake
+++ b/FindNativeClientCPPCache.cmake
@@ -28,41 +28,9 @@
 #   NATIVECLIENT_CPPCACH_DEFINITIONS - Compiler switches required for using NativeClient CPPCache library
 #   NATIVECLIENT_CPPCACH_VERSION_STRING - the version of NativeClient CPPCache library found
 
-find_path(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
-   HINTS
-   ${PC_LIBXML_INCLUDEDIR}
-   ${PC_LIBXML_INCLUDE_DIRS}
-   PATH_SUFFIXES libxml2
-   )
-
-find_library(LIBXML2_LIBRARIES NAMES xml2 libxml2
-   HINTS
-   ${PC_LIBXML_LIBDIR}
-   ${PC_LIBXML_LIBRARY_DIRS}
-   )
-
-find_program(LIBXML2_XMLLINT_EXECUTABLE xmllint)
-
 set( NATIVECLIENT_CPPCACHE_VERSION_STRING "9.0" )
 set( NATIVECLIENT_CPPCACHE_FOUND "YES" )
 set( NATIVECLIENT_CPPCACHE_INCLUDE_DIR  ${CMAKE_CURRENT_BINARY_DIRECTORY}/include ) # TODO: Replace with install directory
 set( NATIVECLIENT_CPPCACHE_LIBRARIES  ${GTK_gtk_LIBRARY}
                     ${GTK_gdk_LIBRARY}
                     ${GTK_glib_LIBRARY} )
-elseif(LIBXML2_INCLUDE_DIR AND EXISTS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h")
-    file(STRINGS "${LIBXML2_INCLUDE_DIR}/libxml/xmlversion.h" libxml2_version_str
-         REGEX "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\".*\"")
-
-    string(REGEX REPLACE "^#define[\t ]+LIBXML_DOTTED_VERSION[\t ]+\"([^\"]*)\".*" "\\1"
-           LIBXML2_VERSION_STRING "${libxml2_version_str}")
-    unset(libxml2_version_str)
-endif()
-
-# handle the QUIETLY and REQUIRED arguments and set LIBXML2_FOUND to TRUE if
-# all listed variables are TRUE
-include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2
-                                  REQUIRED_VARS LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR
-                                  VERSION_VAR LIBXML2_VERSION_STRING)
-
-mark_as_advanced(LIBXML2_INCLUDE_DIR LIBXML2_LIBRARIES LIBXML2_XMLLINT_EXECUTABLE)
diff --git a/clicache/src/DistributedSystem.cpp b/clicache/src/DistributedSystem.cpp
index 42335fa..8c297d9 100644
--- a/clicache/src/DistributedSystem.cpp
+++ b/clicache/src/DistributedSystem.cpp
@@ -316,19 +316,19 @@ namespace Apache
         _GF_MG_EXCEPTION_TRY2
 
           // Set the Generic ManagedCacheLoader/Listener/Writer factory functions.
-          native::CacheXmlParser::managedCacheLoaderFn =
+          native::CacheXmlParser::managedCacheLoaderFn_ =
             native::ManagedCacheLoaderGeneric::create;
-          native::CacheXmlParser::managedCacheListenerFn =
+          native::CacheXmlParser::managedCacheListenerFn_ =
             native::ManagedCacheListenerGeneric::create;
-          native::CacheXmlParser::managedCacheWriterFn =
+          native::CacheXmlParser::managedCacheWriterFn_ =
             native::ManagedCacheWriterGeneric::create;
 
           // Set the Generic ManagedPartitionResolver factory function
-          native::CacheXmlParser::managedPartitionResolverFn =
+          native::CacheXmlParser::managedPartitionResolverFn_ =
             native::ManagedFixedPartitionResolverGeneric::create;
 
           // Set the Generic ManagedPersistanceManager factory function
-          native::CacheXmlParser::managedPersistenceManagerFn =
+          native::CacheXmlParser::managedPersistenceManagerFn_ =
             native::ManagedPersistenceManagerGeneric::create;
 
         _GF_MG_EXCEPTION_CATCH_ALL2
diff --git a/cppcache/CMakeLists.txt b/cppcache/CMakeLists.txt
index da62541..bee0117 100644
--- a/cppcache/CMakeLists.txt
+++ b/cppcache/CMakeLists.txt
@@ -97,7 +97,7 @@ target_link_libraries(_apache-geode INTERFACE
   Boost::boost
   Boost::filesystem
   Boost::thread
-  LibXml2::LibXml2
+  XercesC::XercesC
 )
 
 if (USE_PCH)
diff --git a/cppcache/CPPCacheConfig.cmake b/cppcache/CPPCacheConfig.cmake
index 787ebe4..56145a6 100644
--- a/cppcache/CPPCacheConfig.cmake
+++ b/cppcache/CPPCacheConfig.cmake
@@ -28,21 +28,7 @@
 #   NATIVECLIENT_CPPCACH_DEFINITIONS - Compiler switches required for using NativeClient CPPCache library
 #   NATIVECLIENT_CPPCACH_VERSION_STRING - the version of NativeClient CPPCache library found
 
-#find_path(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
-#   HINTS
-#   ${PC_LIBXML_INCLUDEDIR}
-#   ${PC_LIBXML_INCLUDE_DIRS}
-#   PATH_SUFFIXES libxml2
-#   )
-#
-#find_library(LIBXML2_LIBRARIES NAMES xml2 libxml2
-#   HINTS
-#   ${PC_LIBXML_LIBDIR}
-#   ${PC_LIBXML_LIBRARY_DIRS}
-#   )
-
 set( NATIVECLIENT_CPPCACHE_VERSION_STRING "9.0" )
 set( NATIVECLIENT_CPPCACHE_FOUND "YES" )
 set( NATIVECLIENT_CPPCACHE_INCLUDE_DIR ../../../product/include )
 set( NATIVECLIENT_CPPCACHE_LIBRARIES ../../../product/lib )
-
diff --git a/cppcache/FindCPPCache.cmake b/cppcache/FindCPPCache.cmake
index 787ebe4..56145a6 100644
--- a/cppcache/FindCPPCache.cmake
+++ b/cppcache/FindCPPCache.cmake
@@ -28,21 +28,7 @@
 #   NATIVECLIENT_CPPCACH_DEFINITIONS - Compiler switches required for using NativeClient CPPCache library
 #   NATIVECLIENT_CPPCACH_VERSION_STRING - the version of NativeClient CPPCache library found
 
-#find_path(LIBXML2_INCLUDE_DIR NAMES libxml/xpath.h
-#   HINTS
-#   ${PC_LIBXML_INCLUDEDIR}
-#   ${PC_LIBXML_INCLUDE_DIRS}
-#   PATH_SUFFIXES libxml2
-#   )
-#
-#find_library(LIBXML2_LIBRARIES NAMES xml2 libxml2
-#   HINTS
-#   ${PC_LIBXML_LIBDIR}
-#   ${PC_LIBXML_LIBRARY_DIRS}
-#   )
-
 set( NATIVECLIENT_CPPCACHE_VERSION_STRING "9.0" )
 set( NATIVECLIENT_CPPCACHE_FOUND "YES" )
 set( NATIVECLIENT_CPPCACHE_INCLUDE_DIR ../../../product/include )
 set( NATIVECLIENT_CPPCACHE_LIBRARIES ../../../product/lib )
-
diff --git a/cppcache/integration-test/resources/bad_schema.xml b/cppcache/integration-test/resources/bad_schema.xml
new file mode 100644
index 0000000..cfc2c3e
--- /dev/null
+++ b/cppcache/integration-test/resources/bad_schema.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF 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.
+-->
+
+<client-cache
+    xmlns="http://geode.apache.org/schema/cpp-cache"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://geode.apache.org/schema/cpp-cache
+                          http://geode.apache.org/schema/cpp-cache/file_that_does_not_exist.xsd"
+    version="1.0">
+</client-cache>
+
diff --git a/cppcache/integration/framework/CMakeLists.txt b/cppcache/integration/framework/CMakeLists.txt
index 7b4385b..61fb4a1 100644
--- a/cppcache/integration/framework/CMakeLists.txt
+++ b/cppcache/integration/framework/CMakeLists.txt
@@ -18,10 +18,16 @@ get_target_property(JAVAOBJECT_JAR_PATH javaobject JAR_FILE)
 configure_file(TestConfig.cpp.in TestConfig.cpp)
 
 add_library(integration-framework STATIC
-  Gfsh.cpp
-  Framework.cpp
   Cluster.cpp
+  Cluster.h
+  Framework.cpp
+  Framework.h
+  Gfsh.cpp
+  Gfsh.h
   GfshExecute.cpp
+  GfshExecute.h
+  NamedType.h
+  TestConfig.h
   ${CMAKE_CURRENT_BINARY_DIR}/TestConfig.cpp
   )
 
diff --git a/cppcache/integration/framework/Cluster.h b/cppcache/integration/framework/Cluster.h
index e39e5cd..0545fe9 100644
--- a/cppcache/integration/framework/Cluster.h
+++ b/cppcache/integration/framework/Cluster.h
@@ -30,18 +30,7 @@
 
 #include "Framework.h"
 #include "GfshExecute.h"
-
-template <typename T, typename Parameter>
-class NamedType {
- public:
-  explicit NamedType(T const &value) : value_(value) {}
-  explicit NamedType(T &&value) : value_(std::move(value)) {}
-  T &get() { return value_; }
-  T const &get() const { return value_; }
-
- private:
-  T value_;
-};
+#include "NamedType.h"
 
 class Cluster;
 
diff --git a/cppcache/integration/framework/config.h.in b/cppcache/integration/framework/NamedType.h
similarity index 63%
rename from cppcache/integration/framework/config.h.in
rename to cppcache/integration/framework/NamedType.h
index 0ddbd5b..797aab7 100644
--- a/cppcache/integration/framework/config.h.in
+++ b/cppcache/integration/framework/NamedType.h
@@ -17,10 +17,22 @@
 
 #pragma once
 
-#ifndef INTEGRATION_TEST_FRAMEWORK_CONFIG_H
-#define INTEGRATION_TEST_FRAMEWORK_CONFIG_H
+#ifndef INTEGRATION_TEST_FRAMEWORK_NAMEDTYPE_H
+#define INTEGRATION_TEST_FRAMEWORK_NAMEDTYPE_H
 
-#define GFSH_EXECUTABLE "@Geode_gfsh_EXECUTABLE@"
-#define JAVAOBJECT_JAR_PATH "@JAVAOBJECT_JAR_PATH@"
+#include <cstdint>
+#include <string>
 
-#endif  // INTEGRATION_TEST_FRAMEWORK_CONFIG_H
+template <typename T, typename Parameter>
+class NamedType {
+ public:
+  explicit NamedType(T const &value) : value_(value) {}
+  explicit NamedType(T &&value) : value_(std::move(value)) {}
+  T &get() { return value_; }
+  T const &get() const { return value_; }
+
+ private:
+  T value_;
+};
+
+#endif  // INTEGRATION_TEST_FRAMEWORK_NAMEDTYPE_H
diff --git a/cppcache/integration/framework/TestConfig.cpp.in b/cppcache/integration/framework/TestConfig.cpp.in
index 567a290..2b35db3 100644
--- a/cppcache/integration/framework/TestConfig.cpp.in
+++ b/cppcache/integration/framework/TestConfig.cpp.in
@@ -21,6 +21,7 @@ const char *getFrameworkString(FrameworkVariable name) {
   switch(name) {
     case FrameworkVariable::JavaObjectJarPath: return "@JAVAOBJECT_JAR_PATH@";
     case FrameworkVariable::GfShExecutable: return "@Geode_gfsh_EXECUTABLE@";
+    case FrameworkVariable::TestCacheXmlDir: return "@CMAKE_CURRENT_SOURCE_DIR@/../../integration-test/resources";
     default: return "";
   }
 }
diff --git a/cppcache/integration/framework/TestConfig.h b/cppcache/integration/framework/TestConfig.h
index aa4d81e..ac057b9 100644
--- a/cppcache/integration/framework/TestConfig.h
+++ b/cppcache/integration/framework/TestConfig.h
@@ -20,7 +20,7 @@
 #ifndef INTEGRATION_TEST_FRAMEWORK_CONFIG_H
 #define INTEGRATION_TEST_FRAMEWORK_CONFIG_H
 
-enum class FrameworkVariable {JavaObjectJarPath, GfShExecutable};
+enum class FrameworkVariable {JavaObjectJarPath, GfShExecutable, TestCacheXmlDir};
 
 const char *getFrameworkString(FrameworkVariable name);
 
diff --git a/cppcache/integration/test/CMakeLists.txt b/cppcache/integration/test/CMakeLists.txt
index e9f1f71..aec2fa7 100644
--- a/cppcache/integration/test/CMakeLists.txt
+++ b/cppcache/integration/test/CMakeLists.txt
@@ -15,6 +15,7 @@
 
 add_executable(cpp-integration-test
   AuthInitializeTest.cpp
+  CacheXmlTest.cpp
   CommitConflictExceptionTest.cpp
   CqPlusAuthInitializeTest.cpp
   CqTest.cpp
diff --git a/cppcache/integration/test/CacheXmlTest.cpp b/cppcache/integration/test/CacheXmlTest.cpp
new file mode 100644
index 0000000..16a5b00
--- /dev/null
+++ b/cppcache/integration/test/CacheXmlTest.cpp
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF 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.
+ */
+
+#include <framework/Cluster.h>
+#include <framework/Framework.h>
+#include <framework/Gfsh.h>
+#include <framework/TestConfig.h>
+#include <hacks/range.h>
+
+#include <iostream>
+#include <unordered_map>
+
+#include <gtest/gtest.h>
+
+#include <geode/Cache.hpp>
+#include <geode/PoolManager.hpp>
+#include <geode/QueryService.hpp>
+#include <geode/RegionFactory.hpp>
+#include <geode/RegionShortcut.hpp>
+#include <geode/Struct.hpp>
+
+namespace {
+
+using apache::geode::client::Cache;
+
+apache::geode::client::Cache createCacheUsingXmlConfig(
+    const std::string& xmlFile) {
+  using apache::geode::client::CacheFactory;
+
+  CacheFactory cacheFactory;
+
+  auto cache = cacheFactory.set("log-level", "debug")
+                   .set("log-file", "geode_native.log")
+                   .set("statistic-sampling-enabled", "false")
+                   .set("cache-xml-file", xmlFile.c_str())
+                   .create();
+
+  return cache;
+}
+
+/**
+ * Example test using 2 servers and waiting for async tasks to synchronize using
+ * furtures.
+ */
+TEST(CacheXmlTest, loadCacheXml) {
+  auto cacheXml =
+      std::string(getFrameworkString(FrameworkVariable::TestCacheXmlDir)) +
+      "/valid_cache_refid.xml";
+  auto cache = createCacheUsingXmlConfig(cacheXml);
+}
+
+/**
+ * Example test using 2 servers and waiting for async tasks to synchronize using
+ * furtures.
+ */
+TEST(CacheXmlTest, loadCacheXmlWithBadSchema) {
+  auto cacheXml =
+      std::string(getFrameworkString(FrameworkVariable::TestCacheXmlDir)) +
+      "/bad_schema.xml";
+  EXPECT_NO_THROW(createCacheUsingXmlConfig(cacheXml));
+}
+
+}  // namespace
diff --git a/cppcache/src/CacheConfig.cpp b/cppcache/src/CacheConfig.cpp
deleted file mode 100644
index 2fb47c7..0000000
--- a/cppcache/src/CacheConfig.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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
- */
-
-#include "CacheConfig.hpp"
-
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#include <string.h>
-
-namespace apache {
-namespace geode {
-namespace client {
-
-//////////////////////////////////////////////////////////////////////
-// Construction/Destruction
-//////////////////////////////////////////////////////////////////////
-
-CacheConfig::CacheConfig(const char* xmlFileName)
-    : m_doc(nullptr),
-      m_root_element(nullptr)
-
-{
-  m_doc = xmlParseFile(xmlFileName);
-  if (m_doc == nullptr) {
-    throw IllegalArgumentException("Cacheconfig : xmlParseFile");
-  }
-  m_root_element = xmlDocGetRootElement(m_doc);
-  if (m_root_element == nullptr) {
-    throw IllegalArgumentException("Cacheconfig : xmlDocGetRootElement");
-  }
-  if (!parse()) throw IllegalArgumentException("Cacheconfig : parse error");
-  ;
-}
-
-CacheConfig::~CacheConfig() {
-  if (m_doc) xmlFreeDoc(m_doc);
-  xmlCleanupParser();
-}
-
-bool CacheConfig::parse() {
-  if (strcmp(reinterpret_cast<const char*>(m_root_element->name), "cache") ==
-      0) {
-    xmlNode* cur_node = nullptr;
-
-    for (cur_node = m_root_element->children; cur_node;
-         cur_node = cur_node->next) {
-      if (cur_node->type == XML_ELEMENT_NODE) {
-        if (strcmp(reinterpret_cast<const char*>(cur_node->name),
-                   "root-region") == 0) {
-          parseRegion(cur_node);
-        }
-      }
-    }
-    return true;
-  } else {
-    return false;
-  }
-}
-
-bool CacheConfig::parseRegion(xmlNode* node) {
-  xmlChar* name =
-      xmlGetNoNsProp(node, reinterpret_cast<const unsigned char*>("name"));
-
-  if (name != nullptr) {
-    xmlNode* cur_node = nullptr;
-
-    for (cur_node = node->children; cur_node; cur_node = cur_node->next) {
-      if (cur_node->type == XML_ELEMENT_NODE) {
-        if (strcmp(reinterpret_cast<const char*>(cur_node->name),
-                   "region-attributes") == 0) {
-          parseAttributes(reinterpret_cast<const char*>(name), cur_node);
-        }
-      }
-    }
-    return true;
-  }
-  return false;
-}
-
-bool CacheConfig::parseAttributes(const char* name, xmlNode* node) {
-  xmlChar* scope =
-      xmlGetNoNsProp(node, reinterpret_cast<const unsigned char*>("scope"));
-  xmlChar* initialCapacity = xmlGetNoNsProp(
-      node, reinterpret_cast<const unsigned char*>("initial-capacity"));
-  xmlChar* lruLimit = xmlGetNoNsProp(
-      node, reinterpret_cast<const unsigned char*>("lru-entries-limit"));
-  xmlChar* concurrency = xmlGetNoNsProp(
-      node, reinterpret_cast<const unsigned char*>("concurrency-level"));
-  xmlChar* caching = xmlGetNoNsProp(
-      node, reinterpret_cast<const unsigned char*>("caching-enabled"));
-
-  std::string scopeStr =
-      (scope == nullptr ? "invalid" : reinterpret_cast<const char*>(scope));
-  std::string initialCapacityStr =
-      (initialCapacity == nullptr
-           ? "1000"
-           : reinterpret_cast<const char*>(initialCapacity));
-  std::string limitStr =
-      (lruLimit == nullptr ? "0" : reinterpret_cast<const char*>(lruLimit));
-  std::string concStr =
-      (concurrency == nullptr ? "0"
-                              : reinterpret_cast<const char*>(concurrency));
-  std::string cachingStr =
-      (caching == nullptr ? "true" : reinterpret_cast<const char*>(caching));
-
-  auto reg = std::make_shared<RegionConfig>(initialCapacityStr);
-
-  reg->setLru(limitStr);
-  reg->setConcurrency(concStr);
-  reg->setCaching(cachingStr);
-
-  m_regionList.insert(RegionConfigMapT::value_type(name, reg));
-
-  return true;
-}
-
-RegionConfigMapT& CacheConfig::getRegionList() { return m_regionList; }
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
diff --git a/cppcache/src/CacheConfig.hpp b/cppcache/src/CacheConfig.hpp
deleted file mode 100644
index 013a1c2..0000000
--- a/cppcache/src/CacheConfig.hpp
+++ /dev/null
@@ -1,77 +0,0 @@
-#pragma once
-
-#ifndef GEODE_CACHECONFIG_H_
-#define GEODE_CACHECONFIG_H_
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.
- */
-
-#if defined(_MSC_VER) && _MSC_VER > 1000
-#pragma warning(disable : 4786)
-#endif  // _MSC_VER > 1000
-
-#include <map>
-#include <string>
-
-#include <geode/ExceptionTypes.hpp>
-#include <geode/internal/geode_globals.hpp>
-
-#include "DistributedSystem.hpp"
-#include "RegionConfig.hpp"
-
-//
-// Sneaky structure forward decl;
-//
-
-struct _xmlNode;
-struct _xmlDoc;
-typedef struct _xmlDoc xmlDoc;
-typedef struct _xmlNode xmlNode;
-
-namespace apache {
-namespace geode {
-namespace client {
-
-typedef std::map<std::string, std::shared_ptr<RegionConfig>> RegionConfigMapT;
-
-class APACHE_GEODE_EXPORT CacheConfig {
- public:
-  explicit CacheConfig(const char* xmlFileName);
-
-  bool parse();
-
-  bool parseRegion(xmlNode* node);
-
-  bool parseAttributes(const char* name, xmlNode* node);
-
-  RegionConfigMapT& getRegionList();
-
-  virtual ~CacheConfig();
-
- private:
-  CacheConfig();
-
-  xmlDoc* m_doc;
-  xmlNode* m_root_element;
-
-  RegionConfigMapT m_regionList;
-};
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
-
-#endif  // GEODE_CACHECONFIG_H_
diff --git a/cppcache/src/CacheFactory.cpp b/cppcache/src/CacheFactory.cpp
index dd43d1e..135a5a1 100644
--- a/cppcache/src/CacheFactory.cpp
+++ b/cppcache/src/CacheFactory.cpp
@@ -24,7 +24,6 @@
 #include <geode/PoolManager.hpp>
 #include <geode/SystemProperties.hpp>
 
-#include "CacheConfig.hpp"
 #include "CacheImpl.hpp"
 #include "CppCacheLibrary.hpp"
 #include "DiskVersionTag.hpp"
diff --git a/cppcache/src/CacheXml.cpp b/cppcache/src/CacheXml.cpp
deleted file mode 100644
index fad7551..0000000
--- a/cppcache/src/CacheXml.cpp
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.
- */
-
-#include "CacheXml.hpp"
-
-namespace apache {
-namespace geode {
-namespace client {
-
-CacheXml::CacheXml() {
-  /** The name of the <code>cache</code> element */
-  CACHE = "cache";
-  CLIENT_CACHE = "client-cache";
-  PDX = "pdx";
-
-  /** The name of the <code>redundancy-level</code> element */
-  REDUNDANCY_LEVEL = "redundancy-level";
-
-  /** The name of the <code>region</code> element */
-  REGION = "region";
-
-  /** The name of the <code>root-region</code> element */
-  ROOT_REGION = "root-region";
-
-  /** The name of the <code>region-attributes</code> element */
-  REGION_ATTRIBUTES = "region-attributes";
-
-  LRU_ENTRIES_LIMIT = "lru-entries-limit";
-
-  DISK_POLICY = "disk-policy";
-
-  ENDPOINTS = "endpoints";
-
-  /** The name of the <code>region-time-to-live</code> element */
-  REGION_TIME_TO_LIVE = "region-time-to-live";
-
-  /** The name of the <code>region-idle-time</code> element */
-  REGION_IDLE_TIME = "region-idle-time";
-
-  /** The name of the <code>entry-time-to-live</code> element */
-  ENTRY_TIME_TO_LIVE = "entry-time-to-live";
-
-  /** The name of the <code>entry-idle-time</code> element */
-  ENTRY_IDLE_TIME = "entry-idle-time";
-
-  /** The name of the <code>expiration-attributes</code> element */
-  EXPIRATION_ATTRIBUTES = "expiration-attributes";
-
-  /** The name of the <code>cache-loader</code> element */
-  CACHE_LOADER = "cache-loader";
-
-  /** The name of the <code>cache-writer</code> element */
-  CACHE_WRITER = "cache-writer";
-
-  /** The name of the <code>cache-listener</code> element */
-  CACHE_LISTENER = "cache-listener";
-
-  /** The name of the <code>partition-resolver</code> element */
-  PARTITION_RESOLVER = "partition-resolver";
-
-  LIBRARY_NAME = "library-name";
-
-  LIBRARY_FUNCTION_NAME = "library-function-name";
-
-  CACHING_ENABLED = "caching-enabled";
-
-  INTEREST_LIST_ENABLED = "interest-list-enabled";
-
-  MAX_DISTRIBUTE_VALUE_LENGTH_WHEN_CREATE =
-      "max-distribute-value-length-when-create";
-  /** The name of the <code>scope</code> attribute */
-  SCOPE = "scope";
-
-  /** The name of the <code>client-notification</code> attribute */
-  CLIENT_NOTIFICATION_ENABLED = "client-notification";
-
-  /** The name of the <code>initial-capacity</code> attribute */
-  INITIAL_CAPACITY = "initial-capacity";
-
-  /** The name of the <code>initial-capacity</code> attribute */
-  CONCURRENCY_LEVEL = "concurrency-level";
-
-  /** The name of the <code>load-factor</code> attribute */
-  LOAD_FACTOR = "load-factor";
-
-  /** The name of the <code>statistics-enabled</code> attribute */
-  STATISTICS_ENABLED = "statistics-enabled";
-
-  /** The name of the <code>timeout</code> attribute */
-  TIMEOUT = "timeout";
-
-  /** The name of the <code>action</code> attribute */
-  ACTION = "action";
-
-  /** The name of the <code>local</code> value */
-  LOCAL = "local";
-
-  /** The name of the <code>distributed-no-ack</code> value */
-  DISTRIBUTED_NO_ACK = "distributed-no-ack";
-
-  /** The name of the <code>distributed-ack</code> value */
-  DISTRIBUTED_ACK = "distributed-ack";
-
-  /** The name of the <code>global</code> value */
-  GLOBAL = "global";
-
-  /** The name of the <code>invalidate</code> value */
-  INVALIDATE = "invalidate";
-
-  /** The name of the <code>destroy</code> value */
-  DESTROY = "destroy";
-
-  /** The name of the <code>overflow</code> value */
-  OVERFLOWS = "overflows";
-
-  /** The name of the <code>overflow</code> value */
-  PERSIST = "persist";
-
-  /** The name of the <code>none</code> value */
-  NONE = "none";
-
-  /** The name of the <code>local-invalidate</code> value */
-  LOCAL_INVALIDATE = "local-invalidate";
-
-  /** The name of the <code>local-destroy</code> value */
-  LOCAL_DESTROY = "local-destroy";
-
-  /** The name of the <code>persistence-manager</code> value */
-  PERSISTENCE_MANAGER = "persistence-manager";
-
-  /** The name of the <code>properties</code> value */
-  PROPERTIES = "properties";
-
-  /** The name of the <code>property</code> value */
-  PROPERTY = "property";
-
-  CONCURRENCY_CHECKS_ENABLED = "concurrency-checks-enabled";
-
-  TOMBSTONE_TIMEOUT = "tombstone-timeout";
-
-  /** Pool elements and attributes */
-
-  POOL_NAME = "pool-name";
-  POOL = "pool";
-  NAME = "name";
-  LOCATOR = "locator";
-  SERVER = "server";
-  HOST = "host";
-  PORT = "port";
-  IGNORE_UNREAD_FIELDS = "ignore-unread-fields";
-  READ_SERIALIZED = "read-serialized";
-  FREE_CONNECTION_TIMEOUT = "free-connection-timeout";
-  MULTIUSER_SECURE_MODE = "multiuser-authentication";
-  IDLE_TIMEOUT = "idle-timeout";
-  LOAD_CONDITIONING_INTERVAL = "load-conditioning-interval";
-  MAX_CONNECTIONS = "max-connections";
-  MIN_CONNECTIONS = "min-connections";
-  PING_INTERVAL = "ping-interval";
-  UPDATE_LOCATOR_LIST_INTERVAL = "update-locator-list-interval";
-  READ_TIMEOUT = "read-timeout";
-  RETRY_ATTEMPTS = "retry-attempts";
-  SERVER_GROUP = "server-group";
-  SOCKET_BUFFER_SIZE = "socket-buffer-size";
-  STATISTIC_INTERVAL = "statistic-interval";
-  SUBSCRIPTION_ACK_INTERVAL = "subscription-ack-interval";
-  SUBSCRIPTION_ENABLED = "subscription-enabled";
-  SUBSCRIPTION_MTT = "subscription-message-tracking-timeout";
-  SUBSCRIPTION_REDUNDANCY = "subscription-redundancy";
-  THREAD_LOCAL_CONNECTIONS = "thread-local-connections";
-  CLONING_ENABLED = "cloning-enabled";
-  ID = "id";
-  REFID = "refid";
-  PR_SINGLE_HOP_ENABLED = "pr-single-hop-enabled";
-}
-
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
diff --git a/cppcache/src/CacheXml.hpp b/cppcache/src/CacheXml.hpp
deleted file mode 100644
index c614538..0000000
--- a/cppcache/src/CacheXml.hpp
+++ /dev/null
@@ -1,220 +0,0 @@
-#pragma once
-
-#ifndef GEODE_CACHEXML_H_
-#define GEODE_CACHEXML_H_
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF 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.
- */
-
-#include <geode/internal/geode_globals.hpp>
-
-namespace apache {
-namespace geode {
-namespace client {
-
-class APACHE_GEODE_EXPORT CacheXml {
- public:
-  /** The name of the <code>cache</code> element */
-  const char* CACHE;
-
-  /** The name of the <code>client-cache</code> element */
-  const char* CLIENT_CACHE;
-
-  /** The name of the <code>redundancy-level</code> attribute **/
-  const char* REDUNDANCY_LEVEL;
-
-  /** The name of the <code>region</code> element */
-  const char* REGION;
-
-  /** The name of the <code>pdx</code> element */
-  const char* PDX;
-
-  /** The name of the <code>vm-root-region</code> element */
-  const char* ROOT_REGION;
-
-  /** The name of the <code>region-attributes</code> element */
-  const char* REGION_ATTRIBUTES;
-
-  /** The name of the <code>key-constraint</code> element */
-  //  const char* KEY_CONSTRAINT";
-
-  const char* LRU_ENTRIES_LIMIT;
-
-  /** The name of the <code>lru-eviction-action</code> attribute **/
-  const char* DISK_POLICY;
-
-  /** The name of the <code>endpoints</code> attribute **/
-  const char* ENDPOINTS;
-
-  /** The name of the <code>region-time-to-live</code> element */
-  const char* REGION_TIME_TO_LIVE;
-
-  /** The name of the <code>region-idle-time</code> element */
-  const char* REGION_IDLE_TIME;
-
-  /** The name of the <code>entry-time-to-live</code> element */
-  const char* ENTRY_TIME_TO_LIVE;
-
-  /** The name of the <code>entry-idle-time</code> element */
-  const char* ENTRY_IDLE_TIME;
-
-  /** The name of the <code>expiration-attributes</code> element */
-  const char* EXPIRATION_ATTRIBUTES;
-
-  /** The name of the <code>cache-loader</code> element */
-  const char* CACHE_LOADER;
-
-  /** The name of the <code>cache-writer</code> element */
-  const char* CACHE_WRITER;
-
-  /** The name of the <code>cache-listener</code> element */
-  const char* CACHE_LISTENER;
-
-  /** The name of the <code>partition-resolver</code> element */
-  const char* PARTITION_RESOLVER;
-
-  const char* LIBRARY_NAME;
-
-  const char* LIBRARY_FUNCTION_NAME;
-
-  const char* CACHING_ENABLED;
-
-  const char* INTEREST_LIST_ENABLED;
-
-  const char* MAX_DISTRIBUTE_VALUE_LENGTH_WHEN_CREATE;
-
-  /** The name of the <code>scope</code> attribute */
-  const char* SCOPE;
-
-  /** The name of the <code>client-notification</code> attribute */
-  const char* CLIENT_NOTIFICATION_ENABLED;
-
-  /** The name of the <code>keep-alive-timeout</code> attribute */
-  //??  const char* KEEP_ALIVE_TIMEOUT;
-
-  /** The name of the <code>initial-capacity</code> attribute */
-  const char* INITIAL_CAPACITY;
-
-  /** The name of the <code>initial-capacity</code> attribute */
-  const char* CONCURRENCY_LEVEL;
-
-  /** The name of the <code>serialize-values</code> attribute */
-  //  const char* SERIALIZE_VALUES;
-
-  /** The name of the <code>load-factor</code> attribute */
-  const char* LOAD_FACTOR;
-
-  /** The name of the <code>statistics-enabled</code> attribute */
-  const char* STATISTICS_ENABLED;
-
-  /** The name of the <code>timeout</code> attribute */
-  const char* TIMEOUT;
-
-  /** The name of the <code>action</code> attribute */
-  const char* ACTION;
-
-  /** The name of the <code>local</code> value */
-  const char* LOCAL;
-
-  /** The name of the <code>distributed-no-ack</code> value */
-  const char* DISTRIBUTED_NO_ACK;
-
-  /** The name of the <code>distributed-ack</code> value */
-  const char* DISTRIBUTED_ACK;
-
-  /** The name of the <code>global</code> value */
-  const char* GLOBAL;
-
-  /** The name of the <code>invalidate</code> value */
-
-  const char* INVALIDATE;
-
-  /** The name of the <code>destroy</code> value */
-  const char* DESTROY;
-
-  /** The name of the <code>overflows</code> value */
-  const char* OVERFLOWS;
-
-  /** The name of the <code>persist</code> value */
-  const char* PERSIST;
-
-  /** The name of the <code>none</code> value */
-  const char* NONE;
-
-  /** The name of the <code>local-invalidate</code> value */
-  const char* LOCAL_INVALIDATE;
-
-  /** The name of the <code>local-destroy</code> value */
-  const char* LOCAL_DESTROY;
-
-  /** The name of the <code>persistence-manager</code> value */
-  const char* PERSISTENCE_MANAGER;
-
-  /** The name of the <code>properties</code> value */
-  const char* PROPERTIES;
-
-  /** The name of the <code>property</code> value */
-  const char* PROPERTY;
-
-  /** Pool elements and attributes */
-
-  const char* POOL_NAME;
-  const char* POOL;
-  const char* NAME;
-  const char* LOCATOR;
-  const char* SERVER;
-  const char* HOST;
-  const char* PORT;
-  const char* IGNORE_UNREAD_FIELDS;
-  const char* READ_SERIALIZED;
-  const char* FREE_CONNECTION_TIMEOUT;
-  const char* IDLE_TIMEOUT;
-  const char* LOAD_CONDITIONING_INTERVAL;
-  const char* MAX_CONNECTIONS;
-  const char* MIN_CONNECTIONS;
-  const char* PING_INTERVAL;
-  const char* UPDATE_LOCATOR_LIST_INTERVAL;
-  const char* READ_TIMEOUT;
-  const char* RETRY_ATTEMPTS;
-  const char* SERVER_GROUP;
-  const char* SOCKET_BUFFER_SIZE;
-  const char* STATISTIC_INTERVAL;
-  const char* SUBSCRIPTION_ACK_INTERVAL;
-  const char* SUBSCRIPTION_ENABLED;
-  const char* SUBSCRIPTION_MTT;
-  const char* SUBSCRIPTION_REDUNDANCY;
-  const char* THREAD_LOCAL_CONNECTIONS;
-  const char* CLONING_ENABLED;
-  const char* MULTIUSER_SECURE_MODE;
-  const char* PR_SINGLE_HOP_ENABLED;
-  const char* CONCURRENCY_CHECKS_ENABLED;
-  const char* TOMBSTONE_TIMEOUT;
-
-  /** Name of the named region attributes */
-  const char* ID;
-
-  /** reference to a named attribute */
-  const char* REFID;
-
- public:
-  CacheXml();
-};
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
-
-#endif  // GEODE_CACHEXML_H_
diff --git a/cppcache/src/CacheXmlParser.cpp b/cppcache/src/CacheXmlParser.cpp
index 1494b53..8320171 100644
--- a/cppcache/src/CacheXmlParser.cpp
+++ b/cppcache/src/CacheXmlParser.cpp
@@ -38,16 +38,171 @@ namespace apache {
 namespace geode {
 namespace client {
 
-namespace impl {
-void* getFactoryFunc(const std::string& lib, const std::string& funcName);
-}  // namespace impl
-
 namespace {
+/** The name of the <code>cache</code> element */
+auto CACHE = "cache";
+auto CLIENT_CACHE = "client-cache";
+auto PDX = "pdx";
+
+/** The name of the <code>redundancy-level</code> element */
+auto REDUNDANCY_LEVEL = "redundancy-level";
+
+/** The name of the <code>region</code> element */
+auto REGION = "region";
+
+/** The name of the <code>root-region</code> element */
+auto ROOT_REGION = "root-region";
+
+/** The name of the <code>region-attributes</code> element */
+auto REGION_ATTRIBUTES = "region-attributes";
+
+auto LRU_ENTRIES_LIMIT = "lru-entries-limit";
+
+auto DISK_POLICY = "disk-policy";
+
+auto ENDPOINTS = "endpoints";
+
+/** The name of the <code>region-time-to-live</code> element */
+auto REGION_TIME_TO_LIVE = "region-time-to-live";
+
+/** The name of the <code>region-idle-time</code> element */
+auto REGION_IDLE_TIME = "region-idle-time";
+
+/** The name of the <code>entry-time-to-live</code> element */
+auto ENTRY_TIME_TO_LIVE = "entry-time-to-live";
+
+/** The name of the <code>entry-idle-time</code> element */
+auto ENTRY_IDLE_TIME = "entry-idle-time";
+
+/** The name of the <code>expiration-attributes</code> element */
+auto EXPIRATION_ATTRIBUTES = "expiration-attributes";
+
+/** The name of the <code>cache-loader</code> element */
+auto CACHE_LOADER = "cache-loader";
+
+/** The name of the <code>cache-writer</code> element */
+auto CACHE_WRITER = "cache-writer";
+
+/** The name of the <code>cache-listener</code> element */
+auto CACHE_LISTENER = "cache-listener";
+
+/** The name of the <code>partition-resolver</code> element */
+auto PARTITION_RESOLVER = "partition-resolver";
+
+auto LIBRARY_NAME = "library-name";
+
+auto LIBRARY_FUNCTION_NAME = "library-function-name";
+
+auto CACHING_ENABLED = "caching-enabled";
+
+auto INTEREST_LIST_ENABLED = "interest-list-enabled";
+
+auto MAX_DISTRIBUTE_VALUE_LENGTH_WHEN_CREATE =
+    "max-distribute-value-length-when-create";
+/** The name of the <code>scope</code> attribute */
+auto SCOPE = "scope";
+
+/** The name of the <code>client-notification</code> attribute */
+auto CLIENT_NOTIFICATION_ENABLED = "client-notification";
+
+/** The name of the <code>initial-capacity</code> attribute */
+auto INITIAL_CAPACITY = "initial-capacity";
+
+/** The name of the <code>initial-capacity</code> attribute */
+auto CONCURRENCY_LEVEL = "concurrency-level";
+
+/** The name of the <code>load-factor</code> attribute */
+auto LOAD_FACTOR = "load-factor";
+
+/** The name of the <code>statistics-enabled</code> attribute */
+auto STATISTICS_ENABLED = "statistics-enabled";
 
-using apache::geode::client::impl::getFactoryFunc;
+/** The name of the <code>timeout</code> attribute */
+auto TIMEOUT = "timeout";
+
+/** The name of the <code>action</code> attribute */
+auto ACTION = "action";
+
+/** The name of the <code>local</code> value */
+auto LOCAL = "local";
+
+/** The name of the <code>distributed-no-ack</code> value */
+auto DISTRIBUTED_NO_ACK = "distributed-no-ack";
+
+/** The name of the <code>distributed-ack</code> value */
+auto DISTRIBUTED_ACK = "distributed-ack";
+
+/** The name of the <code>global</code> value */
+auto GLOBAL = "global";
+
+/** The name of the <code>invalidate</code> value */
+auto INVALIDATE = "invalidate";
+
+/** The name of the <code>destroy</code> value */
+auto DESTROY = "destroy";
+
+/** The name of the <code>overflow</code> value */
+auto OVERFLOWS = "overflows";
+
+/** The name of the <code>overflow</code> value */
+auto PERSIST = "persist";
+
+/** The name of the <code>none</code> value */
+auto NONE = "none";
+
+/** The name of the <code>local-invalidate</code> value */
+auto LOCAL_INVALIDATE = "local-invalidate";
+
+/** The name of the <code>local-destroy</code> value */
+auto LOCAL_DESTROY = "local-destroy";
+
+/** The name of the <code>persistence-manager</code> value */
+auto PERSISTENCE_MANAGER = "persistence-manager";
+
+/** The name of the <code>property</code> value */
+auto PROPERTY = "property";
+
+auto CONCURRENCY_CHECKS_ENABLED = "concurrency-checks-enabled";
+
+auto TOMBSTONE_TIMEOUT = "tombstone-timeout";
+
+/** Pool elements and attributes */
+
+auto POOL_NAME = "pool-name";
+auto POOL = "pool";
+auto NAME = "name";
+auto VALUE = "value";
+auto LOCATOR = "locator";
+auto SERVER = "server";
+auto HOST = "host";
+auto PORT = "port";
+auto IGNORE_UNREAD_FIELDS = "ignore-unread-fields";
+auto READ_SERIALIZED = "read-serialized";
+auto FREE_CONNECTION_TIMEOUT = "free-connection-timeout";
+auto MULTIUSER_SECURE_MODE = "multiuser-authentication";
+auto IDLE_TIMEOUT = "idle-timeout";
+auto LOAD_CONDITIONING_INTERVAL = "load-conditioning-interval";
+auto MAX_CONNECTIONS = "max-connections";
+auto MIN_CONNECTIONS = "min-connections";
+auto PING_INTERVAL = "ping-interval";
+auto UPDATE_LOCATOR_LIST_INTERVAL = "update-locator-list-interval";
+auto READ_TIMEOUT = "read-timeout";
+auto RETRY_ATTEMPTS = "retry-attempts";
+auto SERVER_GROUP = "server-group";
+auto SOCKET_BUFFER_SIZE = "socket-buffer-size";
+auto STATISTIC_INTERVAL = "statistic-interval";
+auto SUBSCRIPTION_ACK_INTERVAL = "subscription-ack-interval";
+auto SUBSCRIPTION_ENABLED = "subscription-enabled";
+auto SUBSCRIPTION_MTT = "subscription-message-tracking-timeout";
+auto SUBSCRIPTION_REDUNDANCY = "subscription-redundancy";
+auto THREAD_LOCAL_CONNECTIONS = "thread-local-connections";
+auto CLONING_ENABLED = "cloning-enabled";
+auto ID = "id";
+auto REFID = "refid";
+auto PR_SINGLE_HOP_ENABLED = "pr-single-hop-enabled";
 
 std::vector<std::pair<std::string, int>> parseEndPoints(
-    const std::string& str) {
+    const std::string &str) {
   std::vector<std::pair<std::string, int>> endPoints;
   std::string::size_type start = 0;
   std::string::size_type pos = str.find_first_of(',');
@@ -73,153 +228,6 @@ std::vector<std::pair<std::string, int>> parseEndPoints(
 }
 }  // namespace
 
-/////////////////XML Parser Callback functions////////////////////////
-
-extern "C" void startElementSAX2Function(void* ctx, const xmlChar* name,
-                                         const xmlChar** atts) {
-  CacheXmlParser* parser = (CacheXmlParser*)ctx;
-  if (!parser) {
-    Log::error("CacheXmlParser::startElementSAX2Function:Parser is nullptr");
-    return;
-  }
-
-  if ((!parser->isCacheXmlException()) &&
-      (!parser->isIllegalStateException()) &&
-      (!parser->isAnyOtherException())) {
-    try {
-      auto uname =
-          reinterpret_cast<const char*>(const_cast<unsigned char*>(name));
-      if (std::strcmp(uname, parser->CACHE) == 0) {
-        parser->startCache(ctx, atts);
-      } else if (strcmp(uname, parser->CLIENT_CACHE) == 0) {
-        parser->startCache(ctx, atts);
-      } else if (strcmp(uname, parser->PDX) == 0) {
-        parser->startPdx(atts);
-      } else if (strcmp(uname, parser->REGION) == 0) {
-        parser->incNesting();
-        parser->startRegion(atts, parser->isRootLevel());
-      } else if (strcmp(uname, parser->ROOT_REGION) == 0) {
-        parser->incNesting();
-        parser->startRegion(atts, parser->isRootLevel());
-      } else if (strcmp(uname, parser->REGION_ATTRIBUTES) == 0) {
-        parser->startRegionAttributes(atts);
-      } else if (strcmp(uname, parser->REGION_TIME_TO_LIVE) == 0) {
-      } else if (strcmp(uname, parser->REGION_IDLE_TIME) == 0) {
-      } else if (strcmp(uname, parser->ENTRY_TIME_TO_LIVE) == 0) {
-      } else if (strcmp(uname, parser->ENTRY_IDLE_TIME) == 0) {
-      } else if (strcmp(uname, parser->EXPIRATION_ATTRIBUTES) == 0) {
-        parser->startExpirationAttributes(atts);
-      } else if (strcmp(uname, parser->CACHE_LOADER) == 0) {
-        parser->startCacheLoader(atts);
-      } else if (strcmp(uname, parser->CACHE_WRITER) == 0) {
-        parser->startCacheWriter(atts);
-      } else if (strcmp(uname, parser->CACHE_LISTENER) == 0) {
-        parser->startCacheListener(atts);
-      } else if (strcmp(uname, parser->PARTITION_RESOLVER) == 0) {
-        parser->startPartitionResolver(atts);
-      } else if (strcmp(uname, parser->PERSISTENCE_MANAGER) == 0) {
-        parser->startPersistenceManager(atts);
-      } else if (strcmp(uname, parser->PROPERTIES) == 0) {
-      } else if (strcmp(uname, parser->PROPERTY) == 0) {
-        parser->startPersistenceProperties(atts);
-      } else if (strcmp(uname, parser->POOL) == 0) {
-        parser->startPool(atts);
-      } else if (strcmp(uname, parser->LOCATOR) == 0) {
-        parser->startLocator(atts);
-      } else if (strcmp(uname, parser->SERVER) == 0) {
-        parser->startServer(atts);
-      } else {
-        throw CacheXmlException("XML:Unknown XML element \"" +
-                                std::string(uname) + "\"");
-      }
-    } catch (const CacheXmlException& e) {
-      parser->setCacheXmlException();
-      std::string s = e.what();
-      parser->setError(s);
-    } catch (const IllegalStateException& ex) {
-      parser->setIllegalStateException();
-      std::string s = ex.what();
-      parser->setError(s);
-    } catch (const Exception& ex) {
-      parser->setAnyOtherException();
-      std::string s = ex.what();
-      parser->setError(s);
-    }
-  }  // flag
-}
-
-extern "C" void endElementSAX2Function(void* ctx, const xmlChar* name) {
-  CacheXmlParser* parser = (CacheXmlParser*)ctx;
-  if (!parser) {
-    Log::error(
-        "Error occured while xml parsing: "
-        "CacheXmlParser:startElementSAX2Function:Parser is nullptr");
-    return;
-  }
-
-  if ((!parser->isCacheXmlException()) &&
-      (!parser->isIllegalStateException()) &&
-      (!parser->isAnyOtherException())) {
-    try {
-      auto uname =
-          reinterpret_cast<const char*>(const_cast<unsigned char*>(name));
-      if (strcmp(uname, parser->CACHE) == 0) {
-        parser->endCache();
-      } else if (strcmp(uname, parser->CLIENT_CACHE) == 0) {
-        parser->endCache();
-      } else if (strcmp(uname, parser->PDX) == 0) {
-        parser->endPdx();
-      } else if (strcmp(uname, parser->REGION) == 0) {
-        parser->endRegion(parser->isRootLevel());
-        parser->decNesting();
-      } else if (strcmp(uname, parser->ROOT_REGION) == 0) {
-        parser->endRegion(parser->isRootLevel());
-        parser->decNesting();
-      } else if (strcmp(uname, parser->REGION_ATTRIBUTES) == 0) {
-        parser->endRegionAttributes();
-      } else if (strcmp(uname, parser->REGION_TIME_TO_LIVE) == 0) {
-        parser->endRegionTimeToLive();
-      } else if (strcmp(uname, parser->REGION_IDLE_TIME) == 0) {
-        parser->endRegionIdleTime();
-      } else if (strcmp(uname, parser->ENTRY_TIME_TO_LIVE) == 0) {
-        parser->endEntryTimeToLive();
-      } else if (strcmp(uname, parser->ENTRY_IDLE_TIME) == 0) {
-        parser->endEntryIdleTime();
-      } else if (strcmp(uname, parser->EXPIRATION_ATTRIBUTES) == 0) {
-      } else if (strcmp(uname, parser->CACHE_LOADER) == 0) {
-      } else if (strcmp(uname, parser->CACHE_WRITER) == 0) {
-      } else if (strcmp(uname, parser->CACHE_LISTENER) == 0) {
-      } else if (strcmp(uname, parser->PARTITION_RESOLVER) == 0) {
-      } else if (strcmp(uname, parser->PERSISTENCE_MANAGER) == 0) {
-        parser->endPersistenceManager();
-      } else if (strcmp(uname, parser->PROPERTIES) == 0) {
-      } else if (strcmp(uname, parser->PROPERTY) == 0) {
-      } else if (strcmp(uname, parser->POOL) == 0) {
-        parser->endPool();
-      } else if (strcmp(uname, parser->LOCATOR) == 0) {
-        // parser->endLocator();
-      } else if (strcmp(uname, parser->SERVER) == 0) {
-        // parser->endServer();
-      } else {
-        throw CacheXmlException("XML:Unknown XML element \"" +
-                                std::string(uname) + "\"");
-      }
-    } catch (CacheXmlException& e) {
-      parser->setCacheXmlException();
-      std::string s = e.what();
-      parser->setError(s);
-    } catch (IllegalStateException& ex) {
-      parser->setIllegalStateException();
-      std::string s = ex.what();
-      parser->setError(s);
-    } catch (Exception& ex) {
-      parser->setAnyOtherException();
-      std::string s = ex.what();
-      parser->setError(s);
-    }
-  }  // flag
-}
-
 /**
  * warningDebug:
  * @ctxt:  An XML parser context
@@ -229,7 +237,7 @@ extern "C" void endElementSAX2Function(void* ctx, const xmlChar* name) {
  * Display and format a warning messages, gives file, line, position and
  * extra parameters.
  */
-extern "C" void warningDebug(void*, const char* msg, ...) {
+extern "C" void warningDebug(void *, const char *msg, ...) {
   char logmsg[2048];
   va_list args;
   va_start(args, msg);
@@ -239,133 +247,197 @@ extern "C" void warningDebug(void*, const char* msg, ...) {
           logmsg);
 }
 
-/**
- * fatalErrorDebug:
- * @ctxt:  An XML parser context
- * @msg:  the message to display/transmit
- * @...:  extra parameters for the message display
- *
- * Display and format a fatalError messages, gives file, line, position and
- * extra parameters.
- */
-extern "C" void fatalErrorDebug(void* ctx, const char* msg, ...) {
-  char buf[1024];
-  va_list args;
-
-  va_start(args, msg);
-  CacheXmlParser* parser = (CacheXmlParser*)ctx;
-  vsprintf(buf, msg, args);
-  std::string stringMsg(buf);
-  parser->setParserMessage(parser->getParserMessage() + stringMsg);
-  va_end(args);
-}
-
 /////////////End of XML Parser Cackllback functions///////////////
 
 ///////////////static variables of the class////////////////////////
 
-LibraryCacheLoaderFn CacheXmlParser::managedCacheLoaderFn = nullptr;
-LibraryCacheListenerFn CacheXmlParser::managedCacheListenerFn = nullptr;
-LibraryPartitionResolverFn CacheXmlParser::managedPartitionResolverFn = nullptr;
-LibraryCacheWriterFn CacheXmlParser::managedCacheWriterFn = nullptr;
-LibraryPersistenceManagerFn CacheXmlParser::managedPersistenceManagerFn =
+FactoryLoaderFn<CacheLoader> CacheXmlParser::managedCacheLoaderFn_ = nullptr;
+FactoryLoaderFn<CacheListener> CacheXmlParser::managedCacheListenerFn_ =
+    nullptr;
+FactoryLoaderFn<PartitionResolver> CacheXmlParser::managedPartitionResolverFn_ =
     nullptr;
+FactoryLoaderFn<CacheWriter> CacheXmlParser::managedCacheWriterFn_ = nullptr;
+FactoryLoaderFn<PersistenceManager>
+    CacheXmlParser::managedPersistenceManagerFn_ = nullptr;
 
 //////////////////////////////////////////////////////////////////
 
-CacheXmlParser::CacheXmlParser(Cache* cache)
-    : m_cacheCreation(nullptr),
-      m_nestedRegions(0),
-      m_config(nullptr),
-      m_parserMessage(""),
-      m_flagCacheXmlException(false),
-      m_flagIllegalStateException(false),
-      m_flagAnyOtherException(false),
-      m_flagExpirationAttribute(false),
-      m_poolFactory(nullptr),
-      m_cache(cache) {
-  static xmlSAXHandler saxHandler = {
-      nullptr,                  /* internalSubset */
-      nullptr,                  /* isStandalone */
-      nullptr,                  /* hasInternalSubset */
-      nullptr,                  /* hasExternalSubset */
-      nullptr,                  /* resolveEntity */
-      nullptr,                  /* getEntity */
-      nullptr,                  /* entityDecl */
-      nullptr,                  /* notationDecl */
-      nullptr,                  /* attributeDecl */
-      nullptr,                  /* elementDecl */
-      nullptr,                  /* unparsedEntityDecl */
-      nullptr,                  /* setDocumentLocator */
-      nullptr,                  /* startDocument */
-      nullptr,                  /* endDocument */
-      startElementSAX2Function, /* startElement */
-      endElementSAX2Function,   /* endElement */
-      nullptr,                  /* reference */
-      nullptr,                  /* characters */
-      nullptr,                  /* ignorableWhitespace */
-      nullptr,                  /* processingInstruction */
-      nullptr,                  // commentDebug, /* comment */
-      warningDebug,             /* xmlParserWarning */
-      fatalErrorDebug,          /* xmlParserError */
-      nullptr,                  /* xmlParserError */
-      nullptr,                  /* getParameterEntity */
-      nullptr,                  /* cdataBlock; */
-      nullptr,                  /* externalSubset; */
-      XML_SAX2_MAGIC,
-      nullptr,
-      nullptr, /* startElementNs */
-      nullptr, /* endElementNs */
-      nullptr  /* xmlStructuredErrorFunc */
-  };
-
-  m_saxHandler = saxHandler;
-
-  namedRegions = CacheImpl::getRegionShortcut();
+CacheXmlParser::CacheXmlParser(Cache *cache)
+    : cacheCreation_(nullptr),
+      nestedRegions_(0),
+      config_(nullptr),
+      parserMessage_(""),
+      flagCacheXmlException_(false),
+      flagIllegalStateException_(false),
+      flagAnyOtherException_(false),
+      flagExpirationAttribute_(false),
+      namedRegions_(CacheImpl::getRegionShortcut()),
+      poolFactory_(nullptr),
+      cache_(cache) {
+  start_element_map_.emplace(
+      std::make_pair(std::string(CACHE), &CacheXmlParser::startCache));
+  start_element_map_.emplace(
+      std::make_pair(std::string(CLIENT_CACHE), &CacheXmlParser::startCache));
+  start_element_map_.emplace(
+      std::make_pair(std::string(PDX), &CacheXmlParser::startPdx));
+  start_element_map_.emplace(
+      std::make_pair(std::string(REGION), &CacheXmlParser::startRegion));
+  start_element_map_.emplace(
+      std::make_pair(std::string(ROOT_REGION), &CacheXmlParser::startRegion));
+  start_element_map_.emplace(std::make_pair(
+      std::string(REGION_ATTRIBUTES), &CacheXmlParser::startRegionAttributes));
+  start_element_map_.emplace(
+      std::make_pair(std::string(EXPIRATION_ATTRIBUTES),
+                     &CacheXmlParser::startExpirationAttributes));
+  start_element_map_.emplace(std::make_pair(std::string(CACHE_LOADER),
+                                            &CacheXmlParser::startCacheLoader));
+  start_element_map_.emplace(std::make_pair(std::string(CACHE_WRITER),
+                                            &CacheXmlParser::startCacheWriter));
+  start_element_map_.emplace(std::make_pair(
+      std::string(CACHE_LISTENER), &CacheXmlParser::startCacheListener));
+  start_element_map_.emplace(
+      std::make_pair(std::string(PARTITION_RESOLVER),
+                     &CacheXmlParser::startPartitionResolver));
+  start_element_map_.emplace(
+      std::make_pair(std::string(PERSISTENCE_MANAGER),
+                     &CacheXmlParser::startPersistenceManager));
+  start_element_map_.emplace(std::make_pair(
+      std::string(PROPERTY), &CacheXmlParser::startPersistenceProperty));
+  start_element_map_.emplace(
+      std::make_pair(std::string(POOL), &CacheXmlParser::startPool));
+  start_element_map_.emplace(
+      std::make_pair(std::string(LOCATOR), &CacheXmlParser::startLocator));
+  start_element_map_.emplace(
+      std::make_pair(std::string(SERVER), &CacheXmlParser::startServer));
+
+  end_element_map_.emplace(
+      std::make_pair(std::string(CACHE), &CacheXmlParser::endCache));
+  end_element_map_.emplace(
+      std::make_pair(std::string(CLIENT_CACHE), &CacheXmlParser::endCache));
+  end_element_map_.emplace(
+      std::make_pair(std::string(REGION), &CacheXmlParser::endRegion));
+  end_element_map_.emplace(
+      std::make_pair(std::string(ROOT_REGION), &CacheXmlParser::endRegion));
+  end_element_map_.emplace(std::make_pair(
+      std::string(REGION_ATTRIBUTES), &CacheXmlParser::endRegionAttributes));
+  end_element_map_.emplace(std::make_pair(
+      std::string(REGION_TIME_TO_LIVE), &CacheXmlParser::endRegionTimeToLive));
+  end_element_map_.emplace(std::make_pair(std::string(REGION_IDLE_TIME),
+                                          &CacheXmlParser::endRegionIdleTime));
+  end_element_map_.emplace(std::make_pair(std::string(ENTRY_TIME_TO_LIVE),
+                                          &CacheXmlParser::endEntryTimeToLive));
+  end_element_map_.emplace(std::make_pair(std::string(ENTRY_IDLE_TIME),
+                                          &CacheXmlParser::endEntryIdleTime));
+  end_element_map_.emplace(
+      std::make_pair(std::string(PERSISTENCE_MANAGER),
+                     &CacheXmlParser::endPersistenceManager));
+  end_element_map_.emplace(
+      std::make_pair(std::string(POOL), &CacheXmlParser::endPool));
 }
 
-void CacheXmlParser::parseFile(const char* filename) {
-  int res = 0;
-
-  res = xmlSAXUserParseFile(&this->m_saxHandler, this, filename);
+void CacheXmlParser::startElement(const XMLCh *const,
+                                  const XMLCh *const localname,
+                                  const XMLCh *const,
+                                  const xercesc::Attributes &attrs) {
+  auto message = xercesc::XMLString::transcode(localname);
+  auto name = std::string(message);
+  auto iter = start_element_map_.find(name);
+  if (iter != std::end(start_element_map_)) {
+    iter->second(*this, attrs);
+  }
+  xercesc::XMLString::release(&message);
+}
 
-  if (res == -1) {
-    throw CacheXmlException("Xml file " + std::string(filename) + " not found");
+void CacheXmlParser::endElement(const XMLCh *const,
+                                const XMLCh *const localname,
+                                const XMLCh *const) {
+  auto message = xercesc::XMLString::transcode(localname);
+  auto name = std::string(message);
+  auto iter = end_element_map_.find(name);
+  if (iter != std::end(end_element_map_)) {
+    iter->second(*this);
   }
-  handleParserErrors(res);
+  xercesc::XMLString::release(&message);
 }
 
-void CacheXmlParser::parseMemory(const char* buffer, int size) {
-  int res = 0;
-  res = xmlSAXUserParseMemory(&this->m_saxHandler, this, buffer, size);
+void CacheXmlParser::fatalError(const xercesc::SAXParseException &exception) {
+  using namespace xercesc;
+  char *message = XMLString::transcode(exception.getMessage());
+  LOGDEBUG("Fatal Error: \"%s\" at line: %ulld", message,
+           exception.getLineNumber());
+  auto ex = CacheXmlException(message);
+  XMLString::release(&message);
+  throw ex;
+}
 
-  if (res == -1) {
-    throw CacheXmlException("Unable to read buffer.");
+void CacheXmlParser::parseFile(const char *filename) {
+  try {
+    xercesc::XMLPlatformUtils::Initialize();
+  } catch (const xercesc::XMLException &toCatch) {
+    char *message = xercesc::XMLString::transcode(toCatch.getMessage());
+    auto exceptionMessage = "Error parsing XML file: " + std::string(message);
+    xercesc::XMLString::release(&message);
+    throw CacheXmlException(exceptionMessage);
   }
-  handleParserErrors(res);
+
+  auto parser = xercesc::XMLReaderFactory::createXMLReader();
+
+  parser->setFeature(xercesc::XMLUni::fgXercesSchema, false);
+  parser->setContentHandler(this);
+  parser->setErrorHandler(this);
+
+  try {
+    parser->parse(filename);
+  } catch (const xercesc::XMLException &toCatch) {
+    char *message = xercesc::XMLString::transcode(toCatch.getMessage());
+    auto exceptionMessage = "Error parsing XML file: " + std::string(message);
+    xercesc::XMLString::release(&message);
+    throw CacheXmlException(exceptionMessage);
+  } catch (const xercesc::SAXParseException &toCatch) {
+    char *message = xercesc::XMLString::transcode(toCatch.getMessage());
+    auto exceptionMessage = "Error parsing XML file: " + std::string(message);
+    xercesc::XMLString::release(&message);
+    throw CacheXmlException(exceptionMessage);
+  }
+
+  delete parser;
+  xercesc::XMLPlatformUtils::Terminate();
 }
 
-void CacheXmlParser::handleParserErrors(int res) {
-  if (res != 0)  // xml file is not well-formed
-  {
-    Log::error("Error code returned by xml parser is : " + std::to_string(res));
-    throw CacheXmlException("Xml file is not well formed. Error _stack: \n" +
-                            std::string(this->m_parserMessage));
-  }
-  std::string temp = this->getError();
-  if (temp.empty()) {
-    Log::info("Xml file parsed successfully");
-  } else {
-    // well formed, but not according to our specs(dtd errors thrown manually)
-    if (this->m_flagCacheXmlException) {
-      throw CacheXmlException(temp);
-    } else if (this->m_flagIllegalStateException) {
-      throw IllegalStateException(temp);
-    } else if (this->m_flagAnyOtherException) {
-      throw UnknownException(temp);
-    }
-    this->setError("");
+void CacheXmlParser::parseMemory(const char *buffer, int size) {
+  try {
+    xercesc::XMLPlatformUtils::Initialize();
+  } catch (const xercesc::XMLException &toCatch) {
+    char *message = xercesc::XMLString::transcode(toCatch.getMessage());
+    auto exceptionMessage = "Error parsing XML file: " + std::string(message);
+    xercesc::XMLString::release(&message);
+    throw CacheXmlException(exceptionMessage);
   }
+
+  auto parser = xercesc::XMLReaderFactory::createXMLReader();
+
+  parser->setContentHandler(this);
+  parser->setErrorHandler(this);
+
+  try {
+    xercesc::MemBufInputSource myxml_buf(
+        reinterpret_cast<const XMLByte *>(buffer), size,
+        "CacheXmlParser memory source");
+    parser->parse(myxml_buf);
+  } catch (const xercesc::XMLException &toCatch) {
+    char *message = xercesc::XMLString::transcode(toCatch.getMessage());
+    auto exceptionMessage = "Error parsing XML file: " + std::string(message);
+    xercesc::XMLString::release(&message);
+    throw CacheXmlException(exceptionMessage);
+  } catch (const xercesc::SAXParseException &toCatch) {
+    char *message = xercesc::XMLString::transcode(toCatch.getMessage());
+    auto exceptionMessage = "Error parsing XML file: " + std::string(message);
+    xercesc::XMLString::release(&message);
+    throw CacheXmlException(exceptionMessage);
+  }
+
+  delete parser;
+  xercesc::XMLPlatformUtils::Terminate();
 }
 
 //////////////////////  Static Methods  //////////////////////
@@ -388,8 +460,8 @@ void CacheXmlParser::handleParserErrors(int res) {
  *         If xml file is well-flrmed but not valid
  * @throws UnknownException otherwise
  */
-CacheXmlParser* CacheXmlParser::parse(const char* cacheXml, Cache* cache) {
-  CacheXmlParser* handler;
+CacheXmlParser *CacheXmlParser::parse(const char *cacheXml, Cache *cache) {
+  CacheXmlParser *handler;
   _GEODE_NEW(handler, CacheXmlParser(cache));
   // use RAII to delete the handler object in case of exceptions
   DeleteObject<CacheXmlParser> delHandler(handler);
@@ -401,7 +473,7 @@ CacheXmlParser* CacheXmlParser::parse(const char* cacheXml, Cache* cache) {
   }
 }
 
-void CacheXmlParser::setAttributes(Cache*) {}
+void CacheXmlParser::setAttributes(Cache *) {}
 
 /**
  * Creates cache artifacts ({@link Cache}s, etc.) based upon the XML
@@ -420,286 +492,268 @@ void CacheXmlParser::setAttributes(Cache*) {}
  * @throws UnknownException otherwise
  *
  */
-void CacheXmlParser::create(Cache* cache) {
-  // use DeleteObject class to delete m_cacheCreation in case of exceptions
-  DeleteObject<CacheXmlCreation> delCacheCreation(m_cacheCreation);
+void CacheXmlParser::create(Cache *cache) {
+  // use DeleteObject class to delete cacheCreation_ in case of exceptions
+  DeleteObject<CacheXmlCreation> delCacheCreation(cacheCreation_);
 
   if (cache == nullptr) {
     throw IllegalArgumentException(
         "XML:No cache specified for performing configuration");
   }
-  if (!m_cacheCreation) {
+  if (!cacheCreation_) {
     throw CacheXmlException("XML: Element <cache> was not provided in the xml");
   }
-  m_cacheCreation->create(cache);
+  cacheCreation_->create(cache);
   delCacheCreation.noDelete();
   Log::info("Declarative configuration of cache completed successfully");
 }
 
-void CacheXmlParser::startCache(void*, const xmlChar** atts) {
-  if (atts) {
-    for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-      auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-      auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-      if (value.empty()) {
-        throw CacheXmlException("XML: No value provided for attribute: " +
-                                name);
-      }
+std::string CacheXmlParser::getOptionalAttribute(
+    const xercesc::Attributes &attrs, const char *attributeName) {
+  using unique_xml_char = std::unique_ptr<XMLCh, std::function<void(XMLCh *)>>;
+  using unique_xerces_char = std::unique_ptr<char, std::function<void(char *)>>;
+  auto xml_deleter = [](XMLCh *ch) { xercesc::XMLString::release(&ch); };
+  auto xerces_deleter = [](char *ch) { xercesc::XMLString::release(&ch); };
 
-      if (ENDPOINTS == name) {
-        if (m_poolFactory) {
-          for (auto&& endPoint : parseEndPoints(value)) {
-            m_poolFactory->addServer(endPoint.first, endPoint.second);
-          }
-        }
-      } else if (REDUNDANCY_LEVEL == name) {
-        m_poolFactory->setSubscriptionRedundancy(std::stoi(value));
-      }
-    }
+  unique_xml_char translatedName(xercesc::XMLString::transcode(attributeName),
+                                 xml_deleter);
+  auto value = attrs.getValue(translatedName.get());
+  if (!value) {
+    return "";
   }
-  _GEODE_NEW(m_cacheCreation, CacheXmlCreation());
-}
 
-void CacheXmlParser::startPdx(const xmlChar** atts) {
-  if (!atts) {
-    return;
+  unique_xerces_char translatedValue(xercesc::XMLString::transcode(value),
+                                     xerces_deleter);
+  if (!strlen(translatedValue.get())) {
+    throw CacheXmlException("XML: Empty value provided for attribute: " +
+                            std::string(CACHE) + " or " + CLIENT_CACHE);
   }
 
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-    if (value.empty()) {
-      throw CacheXmlException("XML: No value provided for attribute: " + name);
-    }
-
-    if (IGNORE_UNREAD_FIELDS == name) {
-      bool flag = false;
-      std::transform(value.begin(), value.end(), value.begin(), ::tolower);
-      if ("false" == value) {
-        flag = false;
-      } else if ("true" == value) {
-        flag = true;
-      } else {
-        throw CacheXmlException(
-            "XML: " + value +
-            " is not a valid value for the attribute <ignore-unread-fields>");
-      }
-      m_cacheCreation->setPdxIgnoreUnreadField(flag);
-    } else if (READ_SERIALIZED == name) {
-      bool flag = false;
-      std::transform(value.begin(), value.end(), value.begin(), ::tolower);
-      if ("false" == value) {
-        flag = false;
-      } else if ("true" == value) {
-        flag = true;
-      } else {
-        throw CacheXmlException(
-            "XML: " + value +
-            " is not a valid value for the attribute <ignore-unread-fields>");
-      }
-      m_cacheCreation->setPdxReadSerialized(flag);
-    } else {
-      throw CacheXmlException("XML:Unrecognized pdx attribute " + name);
-    }
-  }
+  return {translatedValue.get()};
 }
 
-void CacheXmlParser::endPdx() {}
+std::string CacheXmlParser::getRequiredAttribute(
+    const xercesc::Attributes &attrs, const char *attributeName) {
+  using unique_xml_char = std::unique_ptr<XMLCh, std::function<void(XMLCh *)>>;
+  auto xml_deleter = [](XMLCh *ch) { xercesc::XMLString::release(&ch); };
 
-void CacheXmlParser::startLocator(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <locator>. A locator requires a host "
-        "and port");
+  unique_xml_char translatedName(xercesc::XMLString::transcode(attributeName),
+                                 xml_deleter);
+  auto value = attrs.getValue(translatedName.get());
+  if (!value) {
+    throw CacheXmlException("XML: No value provided for required attribute: " +
+                            std::string(attributeName));
   }
-  m_poolFactory = std::static_pointer_cast<PoolFactory>(_stack.top());
 
-  std::string host;
-  std::string port;
-  int attrsCount = 0;
-
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-    if (value.empty()) {
-      throw CacheXmlException("XML: No value provided for attribute: " + name);
-    }
+  return getOptionalAttribute(attrs, attributeName);
+}
 
-    if (HOST == name) {
-      host = std::move(value);
-    } else if (PORT == name) {
-      port = std::move(value);
-    } else {
-      throw CacheXmlException("XML:Unrecognized locator attribute");
+void CacheXmlParser::startCache(const xercesc::Attributes &attrs) {
+  auto value = getOptionalAttribute(attrs, ENDPOINTS);
+  if (!value.empty()) {
+    if (poolFactory_) {
+      for (auto &&endPoint : parseEndPoints(value)) {
+        poolFactory_->addServer(endPoint.first, endPoint.second);
+      }
     }
-
-    ++attrsCount;
   }
 
-  if (attrsCount < 2) {
-    throw CacheXmlException(
-        "XML:Not enough attributes provided for a <locator> - host and port "
-        "required");
+  value = getOptionalAttribute(attrs, REDUNDANCY_LEVEL);
+  if (!value.empty()) {
+    if (poolFactory_) {
+      poolFactory_->setSubscriptionRedundancy(std::stoi(value));
+    }
   }
 
-  m_poolFactory->addLocator(host, std::stoi(port));
+  _GEODE_NEW(cacheCreation_, CacheXmlCreation());
 }
 
-void CacheXmlParser::startServer(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <server>. A server requires a host and "
-        "port");
-  }
-  auto factory = std::static_pointer_cast<PoolFactory>(_stack.top());
-
-  std::string host;
-  std::string port;
-  int attrsCount = 0;
-
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-    if (value.empty()) {
-      throw CacheXmlException("XML: No value provided for attribute: " + name);
-    }
-
-    if (HOST == name) {
-      host = std::move(value);
-    } else if (PORT == name) {
-      port = std::move(value);
+void CacheXmlParser::startPdx(const xercesc::Attributes &attrs) {
+  auto ignoreUnreadFields = getOptionalAttribute(attrs, IGNORE_UNREAD_FIELDS);
+  if (!ignoreUnreadFields.empty()) {
+    if (equal_ignore_case(ignoreUnreadFields, "true")) {
+      cacheCreation_->setPdxIgnoreUnreadField(true);
     } else {
-      throw CacheXmlException("XML:Unrecognized server attribute");
+      cacheCreation_->setPdxIgnoreUnreadField(false);
     }
-
-    ++attrsCount;
-  }
-
-  if (attrsCount < 2) {
-    throw CacheXmlException(
-        "XML:Not enough attributes provided for a <server> - host and port "
-        "required");
-  }
-
-  factory->addServer(host, std::stoi(port));
-}
-
-void CacheXmlParser::startPool(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <pool>. A pool cannot be created "
-        "without a name");
   }
-  auto factory =
-      std::make_shared<PoolFactory>(m_cache->getPoolManager().createFactory());
-
-  std::string poolName;
 
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-    if (value.empty()) {
-      throw CacheXmlException("XML: No value provided for attribute: " + name);
-    }
-
-    if (NAME == name) {
-      poolName = std::move(value);
+  auto pdxReadSerialized = getOptionalAttribute(attrs, READ_SERIALIZED);
+  if (!pdxReadSerialized.empty()) {
+    if (equal_ignore_case(pdxReadSerialized, "true")) {
+      cacheCreation_->setPdxReadSerialized(true);
     } else {
-      setPoolInfo(factory.get(), name.c_str(), value.c_str());
+      cacheCreation_->setPdxReadSerialized(false);
     }
   }
+}
 
-  if (poolName.empty()) {
-    throw CacheXmlException(
-        "XML:No attributes provided for a <pool> - at least the name is "
-        "required");
-  }
+void CacheXmlParser::startLocator(const xercesc::Attributes &attrs) {
+  poolFactory_ = std::static_pointer_cast<PoolFactory>(_stack.top());
 
-  auto poolxml = std::make_shared<PoolXmlCreation>(poolName, factory);
+  auto host = getRequiredAttribute(attrs, HOST);
+  auto port = getRequiredAttribute(attrs, PORT);
 
-  _stack.push(poolxml);
-  _stack.push(factory);
+  poolFactory_->addLocator(host, std::stoi(port));
 }
 
-void CacheXmlParser::endPool() {
-  _stack.pop();  // remove factory
-  auto poolxml = std::static_pointer_cast<PoolXmlCreation>(_stack.top());
-  _stack.pop();  // remove pool
-  m_cacheCreation->addPool(poolxml);
+void CacheXmlParser::startServer(const xercesc::Attributes &attrs) {
+  auto factory = std::static_pointer_cast<PoolFactory>(_stack.top());
+
+  auto host = getRequiredAttribute(attrs, HOST);
+  auto port = getRequiredAttribute(attrs, PORT);
+
+  factory->addServer(host, std::stoi(port));
 }
 
-void CacheXmlParser::setPoolInfo(PoolFactory* factory, const char* name,
-                                 const char* value) {
+void CacheXmlParser::startPool(const xercesc::Attributes &attrs) {
   using apache::geode::client::equal_ignore_case;
   using apache::geode::internal::chrono::duration::from_string;
 
-  if (strcmp(name, FREE_CONNECTION_TIMEOUT) == 0) {
+  auto factory =
+      std::make_shared<PoolFactory>(cache_->getPoolManager().createFactory());
+
+  auto poolName = getRequiredAttribute(attrs, NAME);
+
+  auto poolxml = std::make_shared<PoolXmlCreation>(poolName, factory);
+
+  auto freeConnectionTimeout =
+      getOptionalAttribute(attrs, FREE_CONNECTION_TIMEOUT);
+  if (!freeConnectionTimeout.empty()) {
     factory->setFreeConnectionTimeout(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, MULTIUSER_SECURE_MODE) == 0) {
-    if (equal_ignore_case(value, "true")) {
+        from_string<std::chrono::milliseconds>(freeConnectionTimeout));
+  }
+
+  auto multiUserSecureMode = getOptionalAttribute(attrs, MULTIUSER_SECURE_MODE);
+  if (!multiUserSecureMode.empty()) {
+    if (equal_ignore_case(multiUserSecureMode, "true")) {
       factory->setMultiuserAuthentication(true);
     } else {
       factory->setMultiuserAuthentication(false);
     }
-  } else if (strcmp(name, IDLE_TIMEOUT) == 0) {
+  }
+
+  auto idleTimeout = getOptionalAttribute(attrs, IDLE_TIMEOUT);
+  if (!idleTimeout.empty()) {
     factory->setIdleTimeout(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, LOAD_CONDITIONING_INTERVAL) == 0) {
+        from_string<std::chrono::milliseconds>(idleTimeout));
+  }
+
+  auto loadConditioningInterval =
+      getOptionalAttribute(attrs, LOAD_CONDITIONING_INTERVAL);
+  if (!loadConditioningInterval.empty()) {
     factory->setLoadConditioningInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, MAX_CONNECTIONS) == 0) {
-    factory->setMaxConnections(atoi(value));
-  } else if (strcmp(name, MIN_CONNECTIONS) == 0) {
-    factory->setMinConnections(atoi(value));
-  } else if (strcmp(name, PING_INTERVAL) == 0) {
+        from_string<std::chrono::milliseconds>(loadConditioningInterval));
+  }
+
+  auto maxConnections = getOptionalAttribute(attrs, MAX_CONNECTIONS);
+  if (!maxConnections.empty()) {
+    factory->setMaxConnections(atoi(maxConnections.c_str()));
+  }
+
+  auto minConnections = getOptionalAttribute(attrs, MIN_CONNECTIONS);
+  if (!minConnections.empty()) {
+    factory->setMinConnections(atoi(minConnections.c_str()));
+  }
+
+  auto pingInterval = getOptionalAttribute(attrs, PING_INTERVAL);
+  if (!pingInterval.empty()) {
     factory->setPingInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, UPDATE_LOCATOR_LIST_INTERVAL) == 0) {
+        from_string<std::chrono::milliseconds>(std::string(pingInterval)));
+  }
+
+  auto updateLocatorListInterval =
+      getOptionalAttribute(attrs, UPDATE_LOCATOR_LIST_INTERVAL);
+  if (!updateLocatorListInterval.empty()) {
     factory->setUpdateLocatorListInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, READ_TIMEOUT) == 0) {
+        from_string<std::chrono::milliseconds>(updateLocatorListInterval));
+  }
+
+  auto readTimeout = getOptionalAttribute(attrs, READ_TIMEOUT);
+  if (!readTimeout.empty()) {
     factory->setReadTimeout(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, RETRY_ATTEMPTS) == 0) {
-    factory->setRetryAttempts(atoi(value));
-  } else if (strcmp(name, SERVER_GROUP) == 0) {
-    factory->setServerGroup(value);
-  } else if (strcmp(name, SOCKET_BUFFER_SIZE) == 0) {
-    factory->setSocketBufferSize(atoi(value));
-  } else if (strcmp(name, STATISTIC_INTERVAL) == 0) {
+        from_string<std::chrono::milliseconds>(std::string(readTimeout)));
+  }
+
+  auto retryAttempts = getOptionalAttribute(attrs, RETRY_ATTEMPTS);
+  if (!retryAttempts.empty()) {
+    factory->setRetryAttempts(atoi(retryAttempts.c_str()));
+  }
+
+  auto serverGroup = getOptionalAttribute(attrs, SERVER_GROUP);
+  if (!serverGroup.empty()) {
+    factory->setServerGroup(serverGroup);
+  }
+
+  auto socketBufferSize = getOptionalAttribute(attrs, SOCKET_BUFFER_SIZE);
+  if (!socketBufferSize.empty()) {
+    factory->setSocketBufferSize(atoi(socketBufferSize.c_str()));
+  }
+
+  auto statisticInterval = getOptionalAttribute(attrs, STATISTIC_INTERVAL);
+  if (!statisticInterval.empty()) {
     factory->setStatisticInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, SUBSCRIPTION_ACK_INTERVAL) == 0) {
+        from_string<std::chrono::milliseconds>(statisticInterval));
+  }
+
+  auto subscriptionAckInterval =
+      getOptionalAttribute(attrs, SUBSCRIPTION_ACK_INTERVAL);
+  if (!subscriptionAckInterval.empty()) {
     factory->setSubscriptionAckInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, SUBSCRIPTION_ENABLED) == 0) {
-    if (equal_ignore_case(value, "true")) {
+        from_string<std::chrono::milliseconds>(subscriptionAckInterval));
+  }
+
+  auto subscriptionEnabled = getOptionalAttribute(attrs, SUBSCRIPTION_ENABLED);
+  if (!subscriptionEnabled.empty()) {
+    if (equal_ignore_case(subscriptionEnabled, "true")) {
       factory->setSubscriptionEnabled(true);
     } else {
       factory->setSubscriptionEnabled(false);
     }
-  } else if (strcmp(name, SUBSCRIPTION_MTT) == 0) {
+  }
+
+  auto subscriptionMessageTrackingTimeout =
+      getOptionalAttribute(attrs, SUBSCRIPTION_MTT);
+  if (!subscriptionMessageTrackingTimeout.empty()) {
     factory->setSubscriptionMessageTrackingTimeout(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, SUBSCRIPTION_REDUNDANCY) == 0) {
-    factory->setSubscriptionRedundancy(atoi(value));
-  } else if (strcmp(name, THREAD_LOCAL_CONNECTIONS) == 0) {
-    if (equal_ignore_case(value, "true")) {
+        from_string<std::chrono::milliseconds>(
+            subscriptionMessageTrackingTimeout));
+  }
+
+  auto subscriptionRedundancy =
+      getOptionalAttribute(attrs, SUBSCRIPTION_REDUNDANCY);
+  if (!subscriptionRedundancy.empty()) {
+    factory->setSubscriptionRedundancy(atoi(subscriptionRedundancy.c_str()));
+  }
+
+  auto threadLocalConnections =
+      getOptionalAttribute(attrs, THREAD_LOCAL_CONNECTIONS);
+  if (!threadLocalConnections.empty()) {
+    if (equal_ignore_case(threadLocalConnections, "true")) {
       factory->setThreadLocalConnections(true);
     } else {
       factory->setThreadLocalConnections(false);
     }
-  } else if (strcmp(name, PR_SINGLE_HOP_ENABLED) == 0) {
-    if (equal_ignore_case(value, "true")) {
+  }
+
+  auto prSingleHopEnabled = getOptionalAttribute(attrs, PR_SINGLE_HOP_ENABLED);
+  if (!prSingleHopEnabled.empty()) {
+    if (equal_ignore_case(prSingleHopEnabled, "true")) {
       factory->setPRSingleHopEnabled(true);
     } else {
       factory->setPRSingleHopEnabled(false);
     }
-  } else {
-    throw CacheXmlException("XML:Unrecognized pool attribute " +
-                            std::string(name));
   }
+
+  _stack.push(poolxml);
+  _stack.push(factory);
+}
+
+void CacheXmlParser::endPool() {
+  _stack.pop();  // remove factory
+  auto poolxml = std::static_pointer_cast<PoolXmlCreation>(_stack.top());
+  _stack.pop();  // remove pool
+  cacheCreation_->addPool(poolxml);
 }
 
 /**
@@ -707,113 +761,61 @@ void CacheXmlParser::setPoolInfo(PoolFactory* factory, const char* name,
  * create a {@link RegionCreation} and push it on the _stack.
  * An {@link RegionAttributesFactory }is also created and puhed on _stack.
  */
-void CacheXmlParser::startRegion(const xmlChar** atts, bool isRoot) {
-  int attrsCount = 0;
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <region>. A region cannot be created "
-        "without a name");
-  }
-  while (atts[attrsCount]) ++attrsCount;
-  if (attrsCount < 2 || attrsCount > 4) {
-    throw CacheXmlException(
-        "XML:Incorrect number of attributes provided for a <region>");
-  }
-
-  std::string regionName;
-  std::string refid;
-
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-
-    if ("name" == name) {
-      regionName = value;
-    } else if ("refid" == name) {
-      refid = value;
-    } else {
-      throw CacheXmlException("XML:<region> does not contain the attribute :" +
-                              name);
-    }
-  }
-
-  if (regionName.empty()) {
-    throw CacheXmlException(
-        "XML:The attribute name of <region> should be specified and cannot be "
-        "empty");
-  }
+void CacheXmlParser::startRegion(const xercesc::Attributes &attrs) {
+  incNesting();
+  auto isRoot = isRootLevel();
+  auto regionName = getRequiredAttribute(attrs, NAME);
 
   auto region = std::make_shared<RegionXmlCreation>(regionName, isRoot);
   if (!region) {
-    throw UnknownException("CacheXmlParser::startRegion:Out of memeory");
+    throw UnknownException("CacheXmlParser::startRegion:Out of memory");
   }
 
   _stack.push(region);
 
-  RegionAttributesFactory regionAttributesFactory;
+  auto refid = getOptionalAttribute(attrs, REFID);
   if (!refid.empty()) {
-    if (namedRegions.find(refid) != namedRegions.end()) {
-      regionAttributesFactory = RegionAttributesFactory(namedRegions[refid]);
+    if (namedRegions_.find(refid) != namedRegions_.end()) {
+      auto regionAttributesFactory =
+          RegionAttributesFactory(namedRegions_[refid]);
+      region->setAttributes(regionAttributesFactory.create());
     } else {
       throw CacheXmlException("XML:referenced named attribute '" + refid +
                               "' does not exist.");
     }
   }
-
-  region->setAttributes(regionAttributesFactory.create());
-}
-
-void CacheXmlParser::startSubregion(const xmlChar** atts) {
-  startRegion(atts, false);
 }
 
-void CacheXmlParser::startRootRegion(const xmlChar** atts) {
-  startRegion(atts, true);
-}
-
-void CacheXmlParser::startRegionAttributes(const xmlChar** atts) {
+void CacheXmlParser::startRegionAttributes(const xercesc::Attributes &attrs) {
   bool isDistributed = false;
   bool isTCR = false;
   std::shared_ptr<RegionAttributesFactory> regionAttributesFactory = nullptr;
-  if (atts) {
-    int attrsCount = 0;
-    while (atts[attrsCount]) ++attrsCount;
-    if (attrsCount > 24)  // Remember to change this when the number changes
-    {
-      throw CacheXmlException(
-          "XML:Number of attributes provided for <region-attributes> are more");
-    }
 
-    std::string refid;
-
-    for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-      auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-      auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-
-      if (value.empty()) {
-        throw CacheXmlException(
-            "XML:In the <region-attributes> element attribute " + name +
-            " can be set to empty string. It should either have a "
-            "value or the attribute should be removed. In the latter case "
-            "the default value will be set");
-      }
+  if (attrs.getLength() > 24) {
+    throw CacheXmlException(
+        "XML:Too many attributes provided for <region-attributes>");
+  }
 
-      if (ID == name) {
-        auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
-        region->setAttrId(value);
-      } else if (REFID == name) {
-        refid = std::move(value);
-      }
+  if (attrs.getLength() == 0) {
+    auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
+    regionAttributesFactory =
+        std::make_shared<RegionAttributesFactory>(region->getAttributes());
+  } else {
+    auto id = getOptionalAttribute(attrs, ID);
+    if (!id.empty()) {
+      auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
+      region->setAttrId(id);
     }
 
+    auto refid = getOptionalAttribute(attrs, REFID);
     if (refid.empty()) {
       auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
       regionAttributesFactory =
           std::make_shared<RegionAttributesFactory>(region->getAttributes());
     } else {
-      if (namedRegions.find(refid) != namedRegions.end()) {
+      if (namedRegions_.find(refid) != namedRegions_.end()) {
         regionAttributesFactory =
-            std::make_shared<RegionAttributesFactory>(namedRegions[refid]);
+            std::make_shared<RegionAttributesFactory>(namedRegions_[refid]);
       } else {
         throw CacheXmlException("XML:referenced named attribute '" + refid +
                                 "' does not exist.");
@@ -822,119 +824,147 @@ void CacheXmlParser::startRegionAttributes(const xmlChar** atts) {
 
     if (!regionAttributesFactory) {
       throw UnknownException(
-          "CacheXmlParser::startRegionAttributes:Out of memeory");
+          "CacheXmlParser::startRegionAttributes:Out of memory");
     }
 
-    _stack.push(regionAttributesFactory);
-
-    for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-      auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-      auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-
-      if (ID == name || REFID == name) {
-        continue;
-      } else if (CLIENT_NOTIFICATION_ENABLED == name) {
-        bool flag = false;
-        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
-        if ("false" == value) {
-          flag = false;
-        } else if ("true" == value) {
-          flag = true;
-        } else {
-          throw CacheXmlException(
-              "XML: " + value +
-              " is not a valid name for the attribute <client-notification>");
-        }
-        if (m_poolFactory) {
-          m_poolFactory->setSubscriptionEnabled(flag);
-        }
-      } else if (INITIAL_CAPACITY == name) {
-        regionAttributesFactory->setInitialCapacity(std::stoi(value));
-      } else if (CONCURRENCY_LEVEL == name) {
-        regionAttributesFactory->setConcurrencyLevel(std::stoi(value));
-      } else if (LOAD_FACTOR == name) {
-        regionAttributesFactory->setLoadFactor(std::stof(value));
-      } else if (CACHING_ENABLED == name) {
-        bool flag = false;
-        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
-        if ("false" == value) {
-          flag = false;
-        } else if ("true" == value) {
-          flag = true;
-        } else {
-          throw CacheXmlException(
-              "XML: " + value +
-              " is not a valid name for the attribute <caching-enabled>");
-        }
-        regionAttributesFactory->setCachingEnabled(flag);
-      } else if (LRU_ENTRIES_LIMIT == name) {
-        regionAttributesFactory->setLruEntriesLimit(std::stoi(value));
-      } else if (DISK_POLICY == name) {
-        auto diskPolicy = apache::geode::client::DiskPolicyType::NONE;
-        if (OVERFLOWS == value) {
-          diskPolicy = apache::geode::client::DiskPolicyType::OVERFLOWS;
-        } else if (PERSIST == value) {
-          throw IllegalStateException("Persistence feature is not supported");
-        } else if (NONE == value) {
-          diskPolicy = apache::geode::client::DiskPolicyType::NONE;
-        } else {
-          throw CacheXmlException(
-              "XML: " + value +
-              " is not a valid name for the attribute <disk-policy>");
-        }
-        regionAttributesFactory->setDiskPolicy(diskPolicy);
-      } else if (ENDPOINTS == name) {
-        if (m_poolFactory) {
-          for (auto&& endPoint : parseEndPoints(name)) {
-            m_poolFactory->addServer(endPoint.first, endPoint.second);
-          }
-        }
-        isTCR = true;
-      } else if (POOL_NAME == name) {
-        regionAttributesFactory->setPoolName(value);
-        isTCR = true;
-      } else if (CLONING_ENABLED == name) {
-        bool flag = false;
-        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
-        if ("false" == value) {
-          flag = false;
-        } else if ("true" == value) {
-          flag = true;
-        } else {
-          throw CacheXmlException(
-              "XML: " + value +
-              " is not a valid value for the attribute <cloning-enabled>");
-        }
-        regionAttributesFactory->setCloningEnabled(flag);
-        isTCR = true;
-      } else if (CONCURRENCY_CHECKS_ENABLED == name) {
-        bool flag = false;
-        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
-        if ("false" == value) {
-          flag = false;
-        } else if ("true" == value) {
-          flag = true;
-        } else {
-          throw CacheXmlException("XML: " + value +
-                                  " is not a valid value for the attribute "
-                                  "<concurrency-checks-enabled>");
+    auto clientNotificationEnabled =
+        getOptionalAttribute(attrs, CLIENT_NOTIFICATION_ENABLED);
+    if (!clientNotificationEnabled.empty()) {
+      bool flag = false;
+      std::transform(clientNotificationEnabled.begin(),
+                     clientNotificationEnabled.end(),
+                     clientNotificationEnabled.begin(), ::tolower);
+      if ("false" == clientNotificationEnabled) {
+        flag = false;
+      } else if ("true" == clientNotificationEnabled) {
+        flag = true;
+      } else {
+        throw CacheXmlException(
+            "XML: " + clientNotificationEnabled +
+            " is not a valid name for the attribute <client-notification>");
+      }
+      if (poolFactory_) {
+        poolFactory_->setSubscriptionEnabled(flag);
+      }
+    }
+
+    auto initialCapacity = getOptionalAttribute(attrs, INITIAL_CAPACITY);
+    if (!initialCapacity.empty()) {
+      regionAttributesFactory->setInitialCapacity(std::stoi(initialCapacity));
+    }
+
+    auto concurrencyLevel = getOptionalAttribute(attrs, CONCURRENCY_LEVEL);
+    if (!concurrencyLevel.empty()) {
+      regionAttributesFactory->setConcurrencyLevel(std::stoi(concurrencyLevel));
+    }
+
+    auto loadFactor = getOptionalAttribute(attrs, LOAD_FACTOR);
+    if (!loadFactor.empty()) {
+      regionAttributesFactory->setLoadFactor(std::stof(loadFactor));
+    }
+
+    auto cachingEnabled = getOptionalAttribute(attrs, CACHING_ENABLED);
+    if (!cachingEnabled.empty()) {
+      bool flag = false;
+      std::transform(cachingEnabled.begin(), cachingEnabled.end(),
+                     cachingEnabled.begin(), ::tolower);
+      if ("false" == cachingEnabled) {
+        flag = false;
+      } else if ("true" == cachingEnabled) {
+        flag = true;
+      } else {
+        throw CacheXmlException(
+            "XML: " + cachingEnabled +
+            " is not a valid name for the attribute <caching-enabled>");
+      }
+      regionAttributesFactory->setCachingEnabled(flag);
+    }
+
+    auto lruEntriesLimit = getOptionalAttribute(attrs, LRU_ENTRIES_LIMIT);
+    if (!lruEntriesLimit.empty()) {
+      regionAttributesFactory->setLruEntriesLimit(std::stoi(lruEntriesLimit));
+    }
+
+    auto diskPolicyString = getOptionalAttribute(attrs, DISK_POLICY);
+    if (!diskPolicyString.empty()) {
+      auto diskPolicy = apache::geode::client::DiskPolicyType::NONE;
+      if (OVERFLOWS == diskPolicyString) {
+        diskPolicy = apache::geode::client::DiskPolicyType::OVERFLOWS;
+      } else if (PERSIST == diskPolicyString) {
+        throw IllegalStateException("Persistence feature is not supported");
+      } else if (NONE == diskPolicyString) {
+        diskPolicy = apache::geode::client::DiskPolicyType::NONE;
+      } else {
+        throw CacheXmlException(
+            "XML: " + diskPolicyString +
+            " is not a valid name for the attribute <disk-policy>");
+      }
+      regionAttributesFactory->setDiskPolicy(diskPolicy);
+    }
+
+    auto endpoints = getOptionalAttribute(attrs, ENDPOINTS);
+    if (!endpoints.empty()) {
+      if (poolFactory_) {
+        for (auto &&endPoint : parseEndPoints(ENDPOINTS)) {
+          poolFactory_->addServer(endPoint.first, endPoint.second);
         }
-        regionAttributesFactory->setConcurrencyChecksEnabled(flag);
       }
-    }  // for loop
-  }    // atts is nullptr
-  else {
-    auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
-    regionAttributesFactory =
-        std::make_shared<RegionAttributesFactory>(region->getAttributes());
-    _stack.push(regionAttributesFactory);
+      isTCR = true;
+    }
+
+    auto poolName = getOptionalAttribute(attrs, POOL_NAME);
+    if (!poolName.empty()) {
+      regionAttributesFactory->setPoolName(poolName);
+      isTCR = true;
+    }
+
+    auto cloningEnabled = getOptionalAttribute(attrs, CLONING_ENABLED);
+    if (!cloningEnabled.empty()) {
+      bool flag = false;
+      std::transform(cloningEnabled.begin(), cloningEnabled.end(),
+                     cloningEnabled.begin(), ::tolower);
+
+      if ("false" == cloningEnabled) {
+        flag = false;
+      } else if ("true" == cloningEnabled) {
+        flag = true;
+      } else {
+        throw CacheXmlException("XML: " + cloningEnabled +
+                                " is not a valid value for the attribute <" +
+                                std::string(CLONING_ENABLED) + ">");
+      }
+      regionAttributesFactory->setCloningEnabled(flag);
+      isTCR = true;
+    }
+
+    auto concurrencyChecksEnabled =
+        getOptionalAttribute(attrs, CONCURRENCY_CHECKS_ENABLED);
+    if (!concurrencyChecksEnabled.empty()) {
+      bool flag = false;
+      std::transform(concurrencyChecksEnabled.begin(),
+                     concurrencyChecksEnabled.end(),
+                     concurrencyChecksEnabled.begin(), ::tolower);
+      if ("false" == concurrencyChecksEnabled) {
+        flag = false;
+      } else if ("true" == concurrencyChecksEnabled) {
+        flag = true;
+      } else {
+        throw CacheXmlException("XML: " + concurrencyChecksEnabled +
+                                " is not a valid value for the attribute "
+                                "<" +
+                                std::string(CONCURRENCY_CHECKS_ENABLED) + ">");
+      }
+      regionAttributesFactory->setConcurrencyChecksEnabled(flag);
+    }
   }
 
   if (isDistributed && isTCR) {
-    /* we don't allow DR+TCR at current stage according to sudhir */
+    // we don't allow DR+TCR at current stage
     throw CacheXmlException(
         "XML:endpoints cannot be defined for distributed region.\n");
   }
+
+  _stack.push(regionAttributesFactory);
 }
 
 void CacheXmlParser::endRegionAttributes() {
@@ -955,7 +985,7 @@ void CacheXmlParser::endRegionAttributes() {
 
   std::string id = regionPtr->getAttrId();
   if (id != "") {
-    namedRegions[id] = regionAttributes;
+    namedRegions_[id] = regionAttributes;
   }
 
   regionPtr->setAttributes(regionAttributes);
@@ -966,64 +996,45 @@ void CacheXmlParser::endRegionAttributes() {
  * encountered, we create an {@link ExpirationAttibutes} object from
  * the element's attributes and push it on the _stack.
  */
-void CacheXmlParser::startExpirationAttributes(const xmlChar** atts) {
+void CacheXmlParser::startExpirationAttributes(
+    const xercesc::Attributes &attrs) {
   using apache::geode::internal::chrono::duration::from_string;
 
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <expiration-attributes> ");
-  }
-  m_flagExpirationAttribute = true;
-  size_t attrsCount = 0;
-  while (atts[attrsCount]) ++attrsCount;
-  if (attrsCount > 4) {
+  flagExpirationAttribute_ = true;
+
+  if (attrs.getLength() > 2) {
     throw CacheXmlException(
         "XML:Incorrect number of attributes provided for "
-        "<expirartion-attributes>");
+        "<expiration-attributes>");
   }
-  std::string timeOut;
+
   ExpirationAction expire = ExpirationAction::INVALID_ACTION;
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-    if (TIMEOUT == name) {
-      if (value.empty()) {
-        throw CacheXmlException(
-            "XML:Value for attribute <timeout> needs to be specified");
-      }
-      timeOut = value;
-    } else if (ACTION == name) {
-      if (value.empty()) {
-        throw CacheXmlException(
-            "XML:The attribute <action> of <expiration-attributes> cannot be "
-            "set to empty string. It should either have a value or the "
-            "attribute should be removed. In the latter case the default value "
-            "will be set");
-      } else if (INVALIDATE == value) {
-        expire = ExpirationAction::INVALIDATE;
-      } else if (DESTROY == value) {
-        expire = ExpirationAction::DESTROY;
-      } else if (LOCAL_INVALIDATE == value) {
-        expire = ExpirationAction::LOCAL_INVALIDATE;
-      } else if (LOCAL_DESTROY == value) {
-        expire = ExpirationAction::LOCAL_DESTROY;
-      } else {
-        throw CacheXmlException(
-            "XML: " + value +
-            " is not a valid value for the attribute <action>");
-      }
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in "
-          "<expiration-attributes>: " +
-          value);
-    }
+  auto action = getOptionalAttribute(attrs, ACTION);
+  if (action.empty()) {
+    throw CacheXmlException(
+        "XML:The attribute <action> of <expiration-attributes> cannot be"
+        "set to empty string. It should either have a action or the "
+        "attribute should be removed. In the latter case the default action "
+        "will be set");
+  } else if (action == INVALIDATE) {
+    expire = ExpirationAction::INVALIDATE;
+  } else if (action == DESTROY) {
+    expire = ExpirationAction::DESTROY;
+  } else if (action == LOCAL_INVALIDATE) {
+    expire = ExpirationAction::LOCAL_INVALIDATE;
+  } else if (action == LOCAL_DESTROY) {
+    expire = ExpirationAction::LOCAL_DESTROY;
+  } else {
+    throw CacheXmlException("XML: " + action +
+                            " is not a valid value for the attribute <action>");
   }
+
+  auto timeOut = getOptionalAttribute(attrs, TIMEOUT);
   if (timeOut.empty()) {
     throw CacheXmlException(
-        "XML:The attribute <timeout> not specified in "
-        "<expiration-attributes>.");
+        "XML:Value for attribute <timeout> needs to be specified");
   }
+
   auto timeOutSeconds = from_string<std::chrono::seconds>(timeOut);
 
   auto expireAttr =
@@ -1036,270 +1047,69 @@ void CacheXmlParser::startExpirationAttributes(const xmlChar** atts) {
 
   _stack.push(expireAttr);
 }
-void CacheXmlParser::startPersistenceManager(const xmlChar** atts) {
-  int attrsCount = 0;
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <persistence-manager>");
-  }
-  while (atts[attrsCount]) ++attrsCount;
-  if (attrsCount > 4) {
-    throw CacheXmlException(
-        "XML:Incorrect number of attributes provided for "
-        "<persistence-manager>");
-  }
-  std::string libraryName;
-  std::string libraryFunctionName;
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-    if (value.empty()) {
-      throw CacheXmlException("XML:Value for attribute <" + name +
-                              "> needs to be specified in the "
-                              "<persistence-manager>");
-    }
 
-    if (LIBRARY_NAME == name) {
-      libraryName = std::move(value);
-    } else if (LIBRARY_FUNCTION_NAME == name) {
-      libraryFunctionName = std::move(value);
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in <persistence-manager>: " +
-          value);
-    }
-  }
-  if (libraryFunctionName.empty()) {
-    throw CacheXmlException(
-        "XML:Library function name not specified in the <persistence-manager>");
-  }
+std::string CacheXmlParser::getLibraryName(const xercesc::Attributes &attrs) {
+  return getRequiredAttribute(attrs, LIBRARY_NAME);
+}
 
-  try {
-    if (managedPersistenceManagerFn &&
-        libraryFunctionName.find('.') != std::string::npos) {
-      // this is a managed library
-      (*managedPersistenceManagerFn)(libraryName.c_str(),
-                                     libraryFunctionName.c_str());
-    } else {
-      getFactoryFunc(libraryName, libraryFunctionName);
-    }
-  } catch (IllegalArgumentException& ex) {
-    throw CacheXmlException(ex.what());
-  }
+std::string CacheXmlParser::getLibraryFunctionName(
+    const xercesc::Attributes &attrs) {
+  return getRequiredAttribute(attrs, LIBRARY_FUNCTION_NAME);
+}
+
+void CacheXmlParser::startPersistenceManager(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
+
+  verifyFactoryFunction(managedPersistenceManagerFn_, libraryName,
+                        libraryFunctionName);
 
   _stack.emplace(std::make_shared<std::string>(std::move(libraryName)));
   _stack.emplace(std::make_shared<std::string>(std::move(libraryFunctionName)));
 }
 
-void CacheXmlParser::startPersistenceProperties(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException("XML:No attributes provided for <property>");
-  }
-  int attrsCount = 0;
-  while (atts[attrsCount]) ++attrsCount;
-  if (attrsCount > 4) {
-    throw CacheXmlException(
-        "XML:Incorrect number of attributes provided for <property>");
-  } else {
-    if (m_config == nullptr) {
-      m_config = Properties::create();
-    }
-  }
-  std::string propName;
-  std::string propValue;
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-
-    if (value.empty()) {
-      throw CacheXmlException("XML:Value for attribute <" + name +
-                              "> needs to be specified in the "
-                              "<property>");
-    }
+void CacheXmlParser::startPersistenceProperty(
+    const xercesc::Attributes &attrs) {
+  auto propertyName = getRequiredAttribute(attrs, NAME);
+  auto propertyValue = getRequiredAttribute(attrs, VALUE);
 
-    if ("name" == name) {
-      propName = value;
-    } else if ("value" == name) {
-      propValue = value;
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in <property>: " + name);
-    }
+  if (config_ == nullptr) {
+    config_ = Properties::create();
   }
-  if (propName.empty()) {
-    throw CacheXmlException(
-        "XML:attribute <name> needs to be specified in the <property>");
-  }
-  if (propValue.empty()) {
-    throw CacheXmlException(
-        "XML:attribute <value> needs to be  specified in the <property>");
-  }
-  m_config->insert(propName, propValue);
-}
-
-void CacheXmlParser::startCacheLoader(const xmlChar** atts) {
-  std::string libraryName;
-  std::string libraryFunctionName;
-  int attrsCount = 0;
-  if (!atts) {
-    throw CacheXmlException("XML:No attributes provided for <cache-loader>");
-  }
-  while (atts[attrsCount]) ++attrsCount;
-  if (attrsCount > 4) {
-    throw CacheXmlException(
-        "XML:Incorrect number of attributes provided for <cache-loader>");
-  }
-
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
 
-    if (value.empty()) {
-      throw CacheXmlException("XML:Value for attribute <" + name +
-                              "> needs to be specified in the "
-                              "<cache-loader>");
-    }
+  config_->insert(propertyName, propertyValue);
+}
 
-    if (LIBRARY_NAME == name) {
-      libraryName = std::move(value);
-    } else if (LIBRARY_FUNCTION_NAME == name) {
-      libraryFunctionName = std::move(value);
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in <cache-loader> : " + name);
-    }
-  }
-  if (libraryFunctionName.empty()) {
-    throw CacheXmlException(
-        "XML:<library-function-name> not specified in <cache-loader>");
-  }
+void CacheXmlParser::startCacheLoader(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
 
-  try {
-    if (managedCacheLoaderFn &&
-        libraryFunctionName.find('.') != std::string::npos) {
-      // this is a managed library
-      (*managedCacheLoaderFn)(libraryName.c_str(), libraryFunctionName.c_str());
-    } else {
-      getFactoryFunc(libraryName, libraryFunctionName);
-    }
-  } catch (IllegalArgumentException& ex) {
-    throw CacheXmlException(ex.what());
-  }
+  verifyFactoryFunction(managedCacheLoaderFn_, libraryName,
+                        libraryFunctionName);
 
   auto regionAttributesFactory =
       std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
   regionAttributesFactory->setCacheLoader(libraryName, libraryFunctionName);
 }
 
-void CacheXmlParser::startCacheListener(const xmlChar** atts) {
-  std::string libraryName;
-  std::string libraryFunctionName;
-  int attrsCount = 0;
-  if (!atts) {
-    throw CacheXmlException("XML:No attributes provided for <cache-listener>");
-  }
-  while (atts[attrsCount]) ++attrsCount;
-  if (attrsCount > 4) {
-    throw CacheXmlException(
-        "XML:Incorrect number of attributes provided for <cache-listener>");
-  }
-
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-
-    if (value.empty()) {
-      throw CacheXmlException("XML:Value for attribute <" + name +
-                              "> needs to be specified in the "
-                              "<cache-listener>");
-    }
-
-    if (LIBRARY_NAME == name) {
-      libraryName = std::move(value);
-    } else if (LIBRARY_FUNCTION_NAME == name) {
-      libraryFunctionName = std::move(value);
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in <cache-listener> : " +
-          name);
-    }
-  }
-  if (libraryFunctionName.empty()) {
-    throw CacheXmlException(
-        "XML:Library function name not specified in <cache-listener>");
-  }
+void CacheXmlParser::startCacheListener(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
 
-  try {
-    if (managedCacheListenerFn &&
-        libraryFunctionName.find('.') != std::string::npos) {
-      // this is a managed library
-      (*managedCacheListenerFn)(libraryName.c_str(),
-                                libraryFunctionName.c_str());
-    } else {
-      getFactoryFunc(libraryName, libraryFunctionName);
-    }
-  } catch (IllegalArgumentException& ex) {
-    throw CacheXmlException(ex.what());
-  }
+  verifyFactoryFunction(managedCacheListenerFn_, libraryName,
+                        libraryFunctionName);
 
   auto regionAttributesFactory =
       std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
   regionAttributesFactory->setCacheListener(libraryName, libraryFunctionName);
 }
 
-void CacheXmlParser::startPartitionResolver(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <partition-resolver> ");
-  }
+void CacheXmlParser::startPartitionResolver(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
 
-  int attrsCount = 0;
-  while (atts[attrsCount]) ++attrsCount;
-  if (attrsCount > 4) {
-    throw CacheXmlException(
-        "XML:Incorrect number of attributes provided for "
-        "<partition-resolver>");
-  }
-
-  std::string libraryName;
-  std::string libraryFunctionName;
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-
-    if (value.empty()) {
-      throw CacheXmlException("XML:Value for attribute <" + name +
-                              "> needs to be specified in the "
-                              "<cache-listener>");
-    }
-
-    if (LIBRARY_NAME == name) {
-      libraryName = std::move(value);
-    } else if (LIBRARY_FUNCTION_NAME == name) {
-      libraryFunctionName = std::move(value);
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in <partition-resolver>: " +
-          value);
-    }
-  }
-  if (libraryFunctionName.empty()) {
-    throw CacheXmlException(
-        "XML:Library function name not specified in <partition-resolver> ");
-  }
-
-  try {
-    if (managedPartitionResolverFn != nullptr &&
-        libraryFunctionName.find('.') != std::string::npos) {
-      // this is a managed library
-      (*managedPartitionResolverFn)(libraryName.c_str(),
-                                    libraryFunctionName.c_str());
-    } else {
-      getFactoryFunc(libraryName, libraryFunctionName);
-    }
-  } catch (IllegalArgumentException& ex) {
-    throw CacheXmlException(ex.what());
-  }
+  verifyFactoryFunction(managedPartitionResolverFn_, libraryName,
+                        libraryFunctionName);
 
   auto regionAttributesFactory =
       std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
@@ -1307,55 +1117,12 @@ void CacheXmlParser::startPartitionResolver(const xmlChar** atts) {
                                                 libraryFunctionName);
 }
 
-void CacheXmlParser::startCacheWriter(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException("XML:No attributes provided for <cache-writer>");
-  }
-
-  int attrsCount = 0;
-  while (atts[attrsCount] != nullptr) ++attrsCount;
-  if (attrsCount > 4) {
-    throw CacheXmlException(
-        "XML:Incorrect number of attributes provided for <cache-writer>");
-  }
-
-  std::string libraryName;
-  std::string libraryFunctionName;
-
-  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
-    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
-    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
-
-    if (value.empty()) {
-      throw CacheXmlException("XML:Value for attribute <" + name +
-                              "> needs to be specified in the <cache-writer>");
-    }
-
-    if (LIBRARY_NAME == name) {
-      libraryName = std::move(value);
-    } else if (LIBRARY_FUNCTION_NAME == name) {
-      libraryFunctionName = std::move(value);
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in <cache-writer>: " + value);
-    }
-  }
-  if (libraryFunctionName.empty()) {
-    throw CacheXmlException(
-        "XML:Library function name not specified in the <cache-writer>");
-  }
+void CacheXmlParser::startCacheWriter(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
 
-  try {
-    if (managedCacheWriterFn &&
-        libraryFunctionName.find('.') != std::string::npos) {
-      // this is a managed library
-      (*managedCacheWriterFn)(libraryName.c_str(), libraryFunctionName.c_str());
-    } else {
-      getFactoryFunc(libraryName, libraryFunctionName);
-    }
-  } catch (IllegalArgumentException& ex) {
-    throw CacheXmlException(ex.what());
-  }
+  verifyFactoryFunction(managedCacheWriterFn_, libraryName,
+                        libraryFunctionName);
 
   auto regionAttributesFactory =
       std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
@@ -1367,19 +1134,20 @@ void CacheXmlParser::startCacheWriter(const xmlChar** atts) {
  * _stack, if the element on top of the _stack is a
  * <code>RegionXmlCreation</code>, then it is the parent region.
  */
-void CacheXmlParser::endRegion(bool isRoot) {
+void CacheXmlParser::endRegion() {
+  auto isRoot = isRootLevel();
   auto regionPtr = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
   _stack.pop();
   if (isRoot) {
     if (!_stack.empty()) {
       throw CacheXmlException("Xml file has incorrectly nested region tags");
     }
-    if (!m_cacheCreation) {
+    if (!cacheCreation_) {
       throw CacheXmlException(
           "XML: Element <cache> was not provided in the xml");
     }
 
-    m_cacheCreation->addRootRegion(regionPtr);
+    cacheCreation_->addRootRegion(regionPtr);
   } else {
     if (_stack.empty()) {
       throw CacheXmlException("Xml file has incorrectly nested region tags");
@@ -1387,12 +1155,9 @@ void CacheXmlParser::endRegion(bool isRoot) {
     auto parent = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
     parent->addSubregion(regionPtr);
   }
+  decNesting();
 }
 
-void CacheXmlParser::endSubregion() { endRegion(false); }
-
-void CacheXmlParser::endRootRegion() { endRegion(true); }
-
 /**
  * When a <code>cache</code> element is finished
  */
@@ -1405,7 +1170,7 @@ void CacheXmlParser::endCache() {}
  * attributes are assigned.
  */
 void CacheXmlParser::endRegionTimeToLive() {
-  if (!m_flagExpirationAttribute) {
+  if (!flagExpirationAttribute_) {
     throw CacheXmlException(
         "XML: <region-time-to-live> cannot be without a "
         "<expiration-attributes>");
@@ -1419,7 +1184,7 @@ void CacheXmlParser::endRegionTimeToLive() {
       std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
   regionAttributesFactory->setRegionTimeToLive(expireAttr->getAction(),
                                                expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1429,7 +1194,7 @@ void CacheXmlParser::endRegionTimeToLive() {
  * attributes are assigned.
  */
 void CacheXmlParser::endRegionIdleTime() {
-  if (!m_flagExpirationAttribute) {
+  if (!flagExpirationAttribute_) {
     throw CacheXmlException(
         "XML: <region-idle-time> cannot be without <expiration-attributes>");
   }
@@ -1441,7 +1206,7 @@ void CacheXmlParser::endRegionIdleTime() {
 
   regionAttributesFactory->setRegionIdleTimeout(expireAttr->getAction(),
                                                 expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1451,7 +1216,7 @@ void CacheXmlParser::endRegionIdleTime() {
  * attributes are assigned.
  */
 void CacheXmlParser::endEntryTimeToLive() {
-  if (!m_flagExpirationAttribute) {
+  if (!flagExpirationAttribute_) {
     throw CacheXmlException(
         "XML: <entry-time-to-live> cannot be without <expiration-attributes>");
   }
@@ -1463,7 +1228,7 @@ void CacheXmlParser::endEntryTimeToLive() {
 
   regionAttributesFactory->setEntryTimeToLive(expireAttr->getAction(),
                                               expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1473,7 +1238,7 @@ void CacheXmlParser::endEntryTimeToLive() {
  * attributes are assigned.
  */
 void CacheXmlParser::endEntryIdleTime() {
-  if (!m_flagExpirationAttribute) {
+  if (!flagExpirationAttribute_) {
     throw CacheXmlException(
         "XML: <entry-idle-time> cannot be without <expiration-attributes>");
   }
@@ -1485,7 +1250,7 @@ void CacheXmlParser::endEntryIdleTime() {
   // TODO GEODE-3136: consider string parser here.
   regionAttributesFactory->setEntryIdleTimeout(expireAttr->getAction(),
                                                expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1501,21 +1266,17 @@ void CacheXmlParser::endPersistenceManager() {
   _stack.pop();
   auto regionAttributesFactory =
       std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
-  if (m_config != nullptr) {
+  if (config_ != nullptr) {
     regionAttributesFactory->setPersistenceManager(
-        libraryName->c_str(), libraryFunctionName->c_str(), m_config);
-    m_config = nullptr;
+        libraryName->c_str(), libraryFunctionName->c_str(), config_);
+    config_ = nullptr;
   } else {
     regionAttributesFactory->setPersistenceManager(
         libraryName->c_str(), libraryFunctionName->c_str());
   }
 }
 
-CacheXmlParser::~CacheXmlParser() { _GEODE_SAFE_DELETE(m_cacheCreation); }
-
-void CacheXmlParser::setError(const std::string& err) { m_error = err; }
-
-const std::string& CacheXmlParser::getError() const { return m_error; }
+CacheXmlParser::~CacheXmlParser() { _GEODE_SAFE_DELETE(cacheCreation_); }
 
 }  // namespace client
 }  // namespace geode
diff --git a/cppcache/src/CacheXmlParser.hpp b/cppcache/src/CacheXmlParser.hpp
index 09d349b..1353d33 100644
--- a/cppcache/src/CacheXmlParser.hpp
+++ b/cppcache/src/CacheXmlParser.hpp
@@ -20,10 +20,14 @@
  * limitations under the License.
  */
 
-#include <libxml/parser.h>
-
 #include <map>
 #include <stack>
+#include <xercesc/framework/MemBufInputSource.hpp>
+#include <xercesc/sax2/Attributes.hpp>
+#include <xercesc/sax2/DefaultHandler.hpp>
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+#include <xercesc/util/XMLString.hpp>
 
 #include <geode/Cache.hpp>
 #include <geode/CacheListener.hpp>
@@ -34,9 +38,9 @@
 #include <geode/PartitionResolver.hpp>
 #include <geode/RegionShortcut.hpp>
 
-#include "CacheXml.hpp"
 #include "CacheXmlCreation.hpp"
 #include "RegionXmlCreation.hpp"
+#include "Utils.hpp"
 
 namespace apache {
 namespace geode {
@@ -44,39 +48,35 @@ namespace client {
 
 // Factory function typedefs to register the managed
 // cacheloader/writer/listener/resolver
-typedef CacheLoader* (*LibraryCacheLoaderFn)(const char* assemblyPath,
-                                             const char* factFuncName);
-typedef CacheListener* (*LibraryCacheListenerFn)(const char* assemblyPath,
-                                                 const char* factFuncName);
-typedef PartitionResolver* (*LibraryPartitionResolverFn)(
-    const char* assemblyPath, const char* factFuncName);
-typedef CacheWriter* (*LibraryCacheWriterFn)(const char* assemblyPath,
-                                             const char* factFuncName);
-typedef PersistenceManager* (*LibraryPersistenceManagerFn)(
-    const char* assemblyPath, const char* factFuncName);
-
-class APACHE_GEODE_EXPORT CacheXmlParser : public CacheXml {
+template <typename T>
+using FactoryLoaderFn = std::function<T*(const char*, const char*)>;
+
+class CacheXmlParser : public xercesc::DefaultHandler {
+  void startElement(const XMLCh* const uri, const XMLCh* const localname,
+                    const XMLCh* const qname, const xercesc::Attributes& attrs);
+  void endElement(const XMLCh* const uri, const XMLCh* const localname,
+                  const XMLCh* const qname);
+  void fatalError(const xercesc::SAXParseException&);
+
+  std::map<std::string,
+           std::function<void(CacheXmlParser&, const xercesc::Attributes&)>>
+      start_element_map_;
+  std::map<std::string, std::function<void(CacheXmlParser&)>> end_element_map_;
+
  private:
   std::stack<std::shared_ptr<void>> _stack;
-  xmlSAXHandler m_saxHandler;
-  CacheXmlCreation* m_cacheCreation;
-  std::string m_error;
-  int32_t m_nestedRegions;
-  std::shared_ptr<Properties> m_config;
-  std::string m_parserMessage;
-  bool m_flagCacheXmlException;
-  bool m_flagIllegalStateException;
-  bool m_flagAnyOtherException;
-  bool m_flagExpirationAttribute;
-  std::map<std::string, RegionAttributes> namedRegions;
-  std::shared_ptr<PoolFactory> m_poolFactory;
-
-  Cache* m_cache;
-  /** Pool helper */
-  void setPoolInfo(PoolFactory* poolFactory, const char* name,
-                   const char* value);
-
-  void handleParserErrors(int res);
+  CacheXmlCreation* cacheCreation_;
+  int32_t nestedRegions_;
+  std::shared_ptr<Properties> config_;
+  std::string parserMessage_;
+  bool flagCacheXmlException_;
+  bool flagIllegalStateException_;
+  bool flagAnyOtherException_;
+  bool flagExpirationAttribute_;
+  std::map<std::string, RegionAttributes> namedRegions_;
+  std::shared_ptr<PoolFactory> poolFactory_;
+
+  Cache* cache_;
 
  public:
   explicit CacheXmlParser(Cache* cache);
@@ -86,75 +86,89 @@ class APACHE_GEODE_EXPORT CacheXmlParser : public CacheXml {
   void parseMemory(const char* buffer, int size);
   void setAttributes(Cache* cache);
   void create(Cache* cache);
-  void endRootRegion();
-  void endSubregion();
-  void endRegion(bool isRoot);
-  void startExpirationAttributes(const xmlChar** atts);
-  void startPersistenceManager(const xmlChar** atts);
-  void startPersistenceProperties(const xmlChar** atts);
-  void startRegionAttributes(const xmlChar** atts);
-  void startRootRegion(const xmlChar** atts);
-  void startSubregion(const xmlChar** atts);
-  void startPdx(const xmlChar** atts);
-  void endPdx();
-  void startRegion(const xmlChar** atts, bool isRoot);
-  void startCache(void* ctx, const xmlChar** atts);
+  void endRegion();
+  void startExpirationAttributes(const xercesc::Attributes& attrs);
+  void startPersistenceManager(const xercesc::Attributes& attrs);
+  void startPersistenceProperty(const xercesc::Attributes& attrs);
+  void startRegionAttributes(const xercesc::Attributes& attrs);
+  void startPdx(const xercesc::Attributes& attrs);
+  void startRegion(const xercesc::Attributes& attrs);
+  void startCache(const xercesc::Attributes& attrs);
   void endCache();
-  void startCacheLoader(const xmlChar** atts);
-  void startCacheListener(const xmlChar** atts);
-  void startPartitionResolver(const xmlChar** atts);
-  void startCacheWriter(const xmlChar** atts);
+  void startCacheLoader(const xercesc::Attributes& attrs);
+  void startCacheListener(const xercesc::Attributes& attrs);
+  void startPartitionResolver(const xercesc::Attributes& attrs);
+  void startCacheWriter(const xercesc::Attributes& attrs);
   void endEntryIdleTime();
   void endEntryTimeToLive();
   void endRegionIdleTime();
   void endRegionTimeToLive();
   void endRegionAttributes();
   void endPersistenceManager();
-  void setError(const std::string& s);
-  const std::string& getError() const;
-  void incNesting() { m_nestedRegions++; }
-  void decNesting() { m_nestedRegions--; }
-  bool isRootLevel() { return (m_nestedRegions == 1); }
+  void incNesting() { nestedRegions_++; }
+  void decNesting() { nestedRegions_--; }
+  bool isRootLevel() { return (nestedRegions_ == 1); }
 
   /** Pool handlers */
-  void startPool(const xmlChar** atts);
+  void startPool(const xercesc::Attributes& attrs);
   void endPool();
-  void startLocator(const xmlChar** atts);
-  void startServer(const xmlChar** atts);
+  void startLocator(const xercesc::Attributes& attrs);
+  void startServer(const xercesc::Attributes& attrs);
 
   // getters/setters for flags and other members
-  inline bool isCacheXmlException() const { return m_flagCacheXmlException; }
+  inline bool isCacheXmlException() const { return flagCacheXmlException_; }
 
-  inline void setCacheXmlException() { m_flagCacheXmlException = true; }
+  inline void setCacheXmlException() { flagCacheXmlException_ = true; }
 
   inline bool isIllegalStateException() const {
-    return m_flagIllegalStateException;
+    return flagIllegalStateException_;
   }
 
-  inline void setIllegalStateException() { m_flagIllegalStateException = true; }
+  inline void setIllegalStateException() { flagIllegalStateException_ = true; }
 
-  inline bool isAnyOtherException() const { return m_flagAnyOtherException; }
+  inline bool isAnyOtherException() const { return flagAnyOtherException_; }
 
-  inline void setAnyOtherException() { m_flagAnyOtherException = true; }
+  inline void setAnyOtherException() { flagAnyOtherException_ = true; }
 
-  inline bool isExpirationAttribute() const {
-    return m_flagExpirationAttribute;
-  }
+  inline bool isExpirationAttribute() const { return flagExpirationAttribute_; }
 
-  inline void setExpirationAttribute() { m_flagExpirationAttribute = true; }
+  inline void setExpirationAttribute() { flagExpirationAttribute_ = true; }
 
-  inline const std::string& getParserMessage() const { return m_parserMessage; }
+  inline const std::string& getParserMessage() const { return parserMessage_; }
 
-  inline void setParserMessage(const std::string& str) {
-    m_parserMessage = str;
-  }
+  inline void setParserMessage(const std::string& str) { parserMessage_ = str; }
 
   // hooks for .NET managed cache listener/loader/writers
-  static LibraryCacheLoaderFn managedCacheLoaderFn;
-  static LibraryCacheListenerFn managedCacheListenerFn;
-  static LibraryPartitionResolverFn managedPartitionResolverFn;
-  static LibraryCacheWriterFn managedCacheWriterFn;
-  static LibraryPersistenceManagerFn managedPersistenceManagerFn;
+  static FactoryLoaderFn<CacheLoader> managedCacheLoaderFn_;
+  static FactoryLoaderFn<CacheListener> managedCacheListenerFn_;
+  static FactoryLoaderFn<PartitionResolver> managedPartitionResolverFn_;
+  static FactoryLoaderFn<CacheWriter> managedCacheWriterFn_;
+  static FactoryLoaderFn<PersistenceManager> managedPersistenceManagerFn_;
+
+ private:
+  std::string getOptionalAttribute(const xercesc::Attributes& attrs,
+                                   const char* attributeName);
+  std::string getRequiredAttribute(const xercesc::Attributes& attrs,
+                                   const char* attributeName);
+  std::string getLibraryName(const xercesc::Attributes& attrs);
+  std::string getLibraryFunctionName(const xercesc::Attributes& attrs);
+
+  template <typename T>
+  void verifyFactoryFunction(FactoryLoaderFn<T> loader,
+                             const std::string& libraryName,
+                             const std::string& functionName) {
+    try {
+      if (loader && functionName.find('.') != std::string::npos) {
+        // this is a managed library
+        (loader)(libraryName.c_str(), functionName.c_str());
+      } else {
+        apache::geode::client::Utils::getFactoryFunction(libraryName,
+                                                         functionName);
+      }
+    } catch (IllegalArgumentException& ex) {
+      throw CacheXmlException(ex.what());
+    }
+  }
 };
 }  // namespace client
 }  // namespace geode
diff --git a/cppcache/src/RegionAttributes.cpp b/cppcache/src/RegionAttributes.cpp
index 8c37059..32843c6 100644
--- a/cppcache/src/RegionAttributes.cpp
+++ b/cppcache/src/RegionAttributes.cpp
@@ -18,8 +18,6 @@
 #include <cstdlib>
 #include <string>
 
-#include <ace/DLL.h>
-
 #include <geode/Cache.hpp>
 #include <geode/DataInput.hpp>
 #include <geode/DataOutput.hpp>
@@ -33,6 +31,8 @@ namespace apache {
 namespace geode {
 namespace client {
 
+using apache::geode::client::Utils;
+
 RegionAttributes::RegionAttributes()
     : Serializable(),
       m_regionTimeToLiveExpirationAction(ExpirationAction::INVALIDATE),
@@ -59,41 +59,17 @@ RegionAttributes::RegionAttributes()
 
 RegionAttributes::~RegionAttributes() noexcept = default;
 
-namespace impl {
-
-/**
- * lib should be in the form required by ACE_DLL, typically just like specifying
- * a
- * lib in java System.loadLibrary( "x" ); Where x is a component of the name
- * lib<x>.so on unix, or <x>.dll on windows.
- */
-void* getFactoryFunc(const std::string& lib, const std::string& funcName) {
-  ACE_DLL dll;
-  if (dll.open(lib.c_str(), ACE_DEFAULT_SHLIB_MODE, 0) == -1) {
-    throw IllegalArgumentException("cannot open library: " + lib);
-  }
-  void* func = dll.symbol(funcName.c_str());
-  if (func == nullptr) {
-    throw IllegalArgumentException("cannot find factory function " + funcName +
-                                   " in library " + lib);
-  }
-  return func;
-}
-
-}  // namespace impl
-
 std::shared_ptr<CacheLoader> RegionAttributes::getCacheLoader() const {
   if (!m_cacheLoader && !m_cacheLoaderLibrary.empty()) {
-    if (CacheXmlParser::managedCacheLoaderFn &&
+    if (CacheXmlParser::managedCacheLoaderFn_ &&
         m_cacheLoaderFactory.find('.') != std::string::npos) {
       // this is a managed library
-      m_cacheLoader.reset((*CacheXmlParser::managedCacheLoaderFn)(
+      m_cacheLoader.reset((CacheXmlParser::managedCacheLoaderFn_)(
           m_cacheLoaderLibrary.c_str(), m_cacheLoaderFactory.c_str()));
     } else {
       CacheLoader* (*funcptr)();
-      funcptr = reinterpret_cast<CacheLoader* (*)()>(
-          apache::geode::client::impl::getFactoryFunc(m_cacheLoaderLibrary,
-                                                      m_cacheLoaderFactory));
+      funcptr = reinterpret_cast<CacheLoader* (*)()>(Utils::getFactoryFunction(
+          m_cacheLoaderLibrary, m_cacheLoaderFactory));
       m_cacheLoader.reset(funcptr());
     }
   }
@@ -102,16 +78,15 @@ std::shared_ptr<CacheLoader> RegionAttributes::getCacheLoader() const {
 
 std::shared_ptr<CacheWriter> RegionAttributes::getCacheWriter() const {
   if (!m_cacheWriter && !m_cacheWriterLibrary.empty()) {
-    if (CacheXmlParser::managedCacheWriterFn &&
+    if (CacheXmlParser::managedCacheWriterFn_ &&
         m_cacheWriterFactory.find('.') != std::string::npos) {
       // this is a managed library
-      m_cacheWriter.reset((*CacheXmlParser::managedCacheWriterFn)(
+      m_cacheWriter.reset((CacheXmlParser::managedCacheWriterFn_)(
           m_cacheWriterLibrary.c_str(), m_cacheWriterFactory.c_str()));
     } else {
       CacheWriter* (*funcptr)();
-      funcptr = reinterpret_cast<CacheWriter* (*)()>(
-          apache::geode::client::impl::getFactoryFunc(m_cacheWriterLibrary,
-                                                      m_cacheWriterFactory));
+      funcptr = reinterpret_cast<CacheWriter* (*)()>(Utils::getFactoryFunction(
+          m_cacheWriterLibrary, m_cacheWriterFactory));
       m_cacheWriter.reset(funcptr());
     }
   }
@@ -120,16 +95,16 @@ std::shared_ptr<CacheWriter> RegionAttributes::getCacheWriter() const {
 
 std::shared_ptr<CacheListener> RegionAttributes::getCacheListener() const {
   if (!m_cacheListener && !m_cacheListenerLibrary.empty()) {
-    if (CacheXmlParser::managedCacheListenerFn &&
+    if (CacheXmlParser::managedCacheListenerFn_ &&
         m_cacheListenerFactory.find('.') != std::string::npos) {
       // this is a managed library
-      m_cacheListener.reset((*CacheXmlParser::managedCacheListenerFn)(
+      m_cacheListener.reset((CacheXmlParser::managedCacheListenerFn_)(
           m_cacheListenerLibrary.c_str(), m_cacheListenerFactory.c_str()));
     } else {
       CacheListener* (*funcptr)();
-      funcptr = reinterpret_cast<CacheListener* (*)()>(
-          apache::geode::client::impl::getFactoryFunc(m_cacheListenerLibrary,
-                                                      m_cacheListenerFactory));
+      funcptr =
+          reinterpret_cast<CacheListener* (*)()>(Utils::getFactoryFunction(
+              m_cacheListenerLibrary, m_cacheListenerFactory));
       m_cacheListener.reset(funcptr());
     }
   }
@@ -139,16 +114,16 @@ std::shared_ptr<CacheListener> RegionAttributes::getCacheListener() const {
 std::shared_ptr<PartitionResolver> RegionAttributes::getPartitionResolver()
     const {
   if (!m_partitionResolver && !m_partitionResolverLibrary.empty()) {
-    if (CacheXmlParser::managedPartitionResolverFn &&
+    if (CacheXmlParser::managedPartitionResolverFn_ &&
         m_partitionResolverFactory.find('.') != std::string::npos) {
       // this is a managed library
-      m_partitionResolver.reset((*CacheXmlParser::managedPartitionResolverFn)(
+      m_partitionResolver.reset((CacheXmlParser::managedPartitionResolverFn_)(
           m_partitionResolverLibrary.c_str(),
           m_partitionResolverFactory.c_str()));
     } else {
       PartitionResolver* (*funcptr)();
-      funcptr = reinterpret_cast<PartitionResolver* (*)()>(
-          apache::geode::client::impl::getFactoryFunc(
+      funcptr =
+          reinterpret_cast<PartitionResolver* (*)()>(Utils::getFactoryFunction(
               m_partitionResolverLibrary, m_partitionResolverFactory));
       m_partitionResolver.reset(funcptr());
     }
@@ -159,16 +134,16 @@ std::shared_ptr<PartitionResolver> RegionAttributes::getPartitionResolver()
 std::shared_ptr<PersistenceManager> RegionAttributes::getPersistenceManager()
     const {
   if (!m_persistenceManager && !m_persistenceLibrary.empty()) {
-    if (CacheXmlParser::managedPartitionResolverFn &&
+    if (CacheXmlParser::managedPersistenceManagerFn_ &&
         m_persistenceFactory.find('.') != std::string::npos) {
       // this is a managed library
-      m_persistenceManager.reset((*CacheXmlParser::managedPersistenceManagerFn)(
+      m_persistenceManager.reset((CacheXmlParser::managedPersistenceManagerFn_)(
           m_persistenceLibrary.c_str(), m_persistenceFactory.c_str()));
     } else {
       PersistenceManager* (*funcptr)();
-      funcptr = reinterpret_cast<PersistenceManager* (*)()>(
-          apache::geode::client::impl::getFactoryFunc(m_persistenceLibrary,
-                                                      m_persistenceFactory));
+      funcptr =
+          reinterpret_cast<PersistenceManager* (*)()>(Utils::getFactoryFunction(
+              m_persistenceLibrary, m_persistenceFactory));
       m_persistenceManager.reset(funcptr());
     }
   }
diff --git a/cppcache/src/RegionFactory.cpp b/cppcache/src/RegionFactory.cpp
index ab947dd..ffbaf57 100644
--- a/cppcache/src/RegionFactory.cpp
+++ b/cppcache/src/RegionFactory.cpp
@@ -25,7 +25,6 @@
 #include <geode/RegionShortcut.hpp>
 #include <geode/SystemProperties.hpp>
 
-#include "CacheConfig.hpp"
 #include "CacheImpl.hpp"
 #include "CacheRegionHelper.hpp"
 #include "CppCacheLibrary.hpp"
diff --git a/cppcache/src/ThinClientPoolDM.cpp b/cppcache/src/ThinClientPoolDM.cpp
index 0560393..4eaaca9 100644
--- a/cppcache/src/ThinClientPoolDM.cpp
+++ b/cppcache/src/ThinClientPoolDM.cpp
@@ -162,9 +162,11 @@ ThinClientPoolDM::ThinClientPoolDM(const char* name,
       m_PoolStatsSampler(nullptr),
       m_clientMetadataService(nullptr),
       m_primaryServerQueueSize(PRIMARY_QUEUE_NOT_AVAILABLE) {
-  static bool firstGurd = false;
-  if (firstGurd) ClientProxyMembershipID::increaseSynchCounter();
-  firstGurd = true;
+  static bool firstGuard = false;
+  if (firstGuard) {
+    ClientProxyMembershipID::increaseSynchCounter();
+  }
+  firstGuard = true;
 
   auto cacheImpl = m_connManager.getCacheImpl();
   auto& distributedSystem = cacheImpl->getDistributedSystem();
diff --git a/cppcache/src/Utils.cpp b/cppcache/src/Utils.cpp
index 48004c8..b7b2c32 100644
--- a/cppcache/src/Utils.cpp
+++ b/cppcache/src/Utils.cpp
@@ -23,6 +23,7 @@
 #include <iomanip>
 #include <sstream>
 
+#include <ace/DLL.h>
 #include <ace/INET_Addr.h>
 #include <ace/OS.h>
 
@@ -150,6 +151,20 @@ char* Utils::copyString(const char* str) {
   return resStr;
 }
 
+void* Utils::getFactoryFunction(const std::string& lib,
+                                const std::string& funcName) {
+  ACE_DLL dll;
+  if (dll.open(lib.c_str(), ACE_DEFAULT_SHLIB_MODE, 0) == -1) {
+    throw IllegalArgumentException("cannot open library: " + lib);
+  }
+  void* func = dll.symbol(funcName.c_str());
+  if (func == nullptr) {
+    throw IllegalArgumentException("cannot find factory function " + funcName +
+                                   " in library " + lib);
+  }
+  return func;
+}
+
 std::string Utils::convertBytesToString(const uint8_t* bytes, size_t length,
                                         size_t maxLength) {
   if (bytes != nullptr) {
diff --git a/cppcache/src/Utils.hpp b/cppcache/src/Utils.hpp
index 39de1c7..8e6877a 100644
--- a/cppcache/src/Utils.hpp
+++ b/cppcache/src/Utils.hpp
@@ -165,6 +165,16 @@ class APACHE_GEODE_EXPORT Utils {
                                           size_t maxLength = _GF_MSG_LIMIT);
 
   /**
+   * lib should be in the form required by ACE_DLL, typically just like
+   * specifying
+   * a
+   * lib in java System.loadLibrary( "x" ); Where x is a component of the name
+   * lib<x>.so on unix, or <x>.dll on windows.
+   */
+  static void* getFactoryFunction(const std::string& lib,
+                                  const std::string& funcName);
+
+  /**
    * Convert the byte array to a string as "%d %d ...".
    * <code>maxLength</code> as zero implies no limit.
    */
diff --git a/cppcache/test/CacheXmlParserTest.cpp b/cppcache/test/CacheXmlParserTest.cpp
index d4a91ad..4387da3 100644
--- a/cppcache/test/CacheXmlParserTest.cpp
+++ b/cppcache/test/CacheXmlParserTest.cpp
@@ -23,13 +23,14 @@ using apache::geode::client::CacheXmlParser;
 
 std::string xsd_prefix = R"(<?xml version='1.0' encoding='UTF-8'?>
 <client-cache
+  xmlns="http://geode.apache.org/schema/cpp-cache"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xmlns="http://geode.apache.org/schema/cache"
-  xsi:schemaLocation="http://geode.apache.org/schema/cpp-cache-1.0.xsd"
-  version='10.0'
+  xsi:schemaLocation="http://geode.apache.org/schema/cpp-cache
+                      http//geode.apache.org/schema/cpp-cache/cpp-cache-1.0.xsd"
+  version='1.0'
 >)";
 
-std::string valid_cache_config_body = R"(<root-region name = 'Root1' >
+std::string valid_cache_config_body = R"(<region name = 'Root1' >
         <region-attributes scope='local'
                            caching-enabled='true'
                            initial-capacity='25'
@@ -57,8 +58,8 @@ std::string valid_cache_config_body = R"(<root-region name = 'Root1' >
                                concurrency-level='52'>
             </region-attributes>
         </region>
-    </root-region>
-    <root-region name= 'Root2'>
+    </region>
+    <region name= 'Root2'>
         <region-attributes scope='local'
                            caching-enabled='true'
                            initial-capacity='16'
@@ -95,7 +96,76 @@ std::string valid_cache_config_body = R"(<root-region name = 'Root1' >
             <region name='SubSubRegion221'>
             </region>
         </region>
-    </root-region>
+    </region>
+</client-cache>)";
+
+std::string invalid_cache_config_body = R"(<region >
+        <region-attributes scope='local'
+                           caching-enabled='true'
+                           initial-capacity='25'
+                           load-factor='0.32'
+                           concurrency-level='10'
+                           lru-entries-limit = '35'>
+            <region-idle-time>
+                <expiration-attributes timeout='20s' action='destroy'/>
+            </region-idle-time>
+            <entry-idle-time>
+                <expiration-attributes timeout='10s' action='invalidate'/>
+            </entry-idle-time>
+            <region-time-to-live>
+                <expiration-attributes timeout='0s' action='local-destroy'/>
+            </region-time-to-live>
+            <entry-time-to-live>
+                <expiration-attributes timeout='0s' action='local-invalidate'/>
+            </entry-time-to-live>
+        </region-attributes>
+        <region name='SubRegion1'>
+            <region-attributes scope='local'
+                               caching-enabled='true'
+                               initial-capacity='23'
+                               load-factor='0.89'
+                               concurrency-level='52'>
+            </region-attributes>
+        </region>
+    </region>
+    <region name= 'Root2'>
+        <region-attributes scope='local'
+                           caching-enabled='true'
+                           initial-capacity='16'
+                           load-factor='0.75'
+                           concurrency-level='16'>
+            <region-time-to-live>
+                <expiration-attributes timeout='0s' action='destroy'/>
+            </region-time-to-live>
+            <region-idle-time>
+                <expiration-attributes timeout='0s' action='invalidate'/>
+            </region-idle-time>
+            <entry-time-to-live>
+                <expiration-attributes timeout='0s' action='destroy'/>
+            </entry-time-to-live>
+            <entry-idle-time>
+                <expiration-attributes timeout='0s' action='invalidate'/>
+            </entry-idle-time>
+        </region-attributes>
+        <region name='SubRegion21'>
+            <region-attributes scope='local'
+                               caching-enabled='true'
+                               initial-capacity='16'
+                               load-factor='0.75'
+                               concurrency-level='16'>
+                <region-idle-time>
+                    <expiration-attributes timeout='20s' action='destroy'/>
+                </region-idle-time>
+                <entry-idle-time>
+                    <expiration-attributes timeout='10s' action='invalidate'/>
+                </entry-idle-time>
+            </region-attributes>
+        </region>
+        <region name='SubRegion22'>
+            <region name='SubSubRegion221'>
+            </region>
+        </region>
+    </region>
 </client-cache>)";
 
 TEST(CacheXmlParser, CanParseRegionConfigFromAValidXsdCacheConfig) {
@@ -103,3 +173,10 @@ TEST(CacheXmlParser, CanParseRegionConfigFromAValidXsdCacheConfig) {
   std::string xml = xsd_prefix + valid_cache_config_body;
   parser.parseMemory(xml.c_str(), static_cast<int>(xml.length()));
 }
+
+TEST(CacheXmlParser, ParseRegionConfigFromInvalidCacheConfigThrowsException) {
+  CacheXmlParser parser(nullptr);
+  std::string xml = xsd_prefix + invalid_cache_config_body;
+  ASSERT_THROW(parser.parseMemory(xml.c_str(), static_cast<int>(xml.length())),
+               apache::geode::client::CacheXmlException);
+}
diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt
index b5fbe29..236fe06 100644
--- a/dependencies/CMakeLists.txt
+++ b/dependencies/CMakeLists.txt
@@ -18,13 +18,13 @@ project( dependencies LANGUAGES NONE )
 
 find_package(Patch REQUIRED)
 
-add_subdirectory(	libxml2 )
 add_subdirectory(	ACE )
 add_subdirectory(	boost )
 add_subdirectory(	sqlite )
 add_subdirectory(	doxygen )
 add_subdirectory(	gtest )
 add_subdirectory(	benchmark )
+add_subdirectory(	xerces-c )
 
 if (USE_RAT)
   add_subdirectory( rat )
diff --git a/dependencies/libxml2/CMakeLists.txt b/dependencies/libxml2/CMakeLists.txt
deleted file mode 100644
index aabd6c8..0000000
--- a/dependencies/libxml2/CMakeLists.txt
+++ /dev/null
@@ -1,91 +0,0 @@
-# Licensed to the Apache Software Foundation (ASF) under one or more
-# contributor license agreements.  See the NOTICE file distributed with
-# this work for additional information regarding copyright ownership.
-# The ASF 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.
-
-project( libxml2 VERSION 2.9.9 LANGUAGES NONE )
-
-set( SHA256 94fb70890143e3c6549f265cee93ec064c80a84c42ad0f23e85ee1fd6540a871 )
-
-set( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64" )
-
-if (${WIN32})
-  set (_MAKE_FLAGS ${_MAKE_FLAGS} "CPP=cl.exe /MP /EP" "CC=cl.exe /MP" )
-  set (_MAKE_FLAGS ${_MAKE_FLAGS}
-                          DEBUG=$<STREQUAL:$<CONFIG>,Debug>
-                          CRUNTIME=/MD$<$<CONFIG:Debug>:d>
-                          XML_SO=libxml2$<$<CONFIG:Debug>:d>.dll
-                          XML_IMP=libxml2$<$<CONFIG:Debug>:d>.lib
-                          XML_A=libxml2_a$<$<CONFIG:Debug>:d>.lib
-                          XML_A_DLL=libxml2_a_dll$<$<CONFIG:Debug>:d>.lib
-                          XML_INTDIR=int$<$<CONFIG:Debug>:d>.msvc
-                          XML_INTDIR_A=int$<$<CONFIG:Debug>:d>.a.msvc
-                          XML_INTDIR_A_DLL=int$<$<CONFIG:Debug>:d>.a.dll.msvc
-                          UTILS_INTDIR=int$<$<CONFIG:Debug>:d>.utils.msvc )
-
-  # http://hostagebrain.blogspot.com/2015/06/building-libxml2-without-dependencies.html
-  set ( _CONFIGURE_COMMAND ${CMAKE_COMMAND} -E chdir win32 cscript configure.js iconv=no compiler=msvc cruntime=/MD$<$<CONFIG:Debug>:d> debug=$<$<CONFIG:Debug>:yes>$<$<NOT:$<CONFIG:Debug>>:no> prefix=..\\..\\.. static=yes )
-  set ( _BUILD_COMMAND ${CMAKE_COMMAND} -E chdir win32 nmake -f Makefile.msvc all ${_MAKE_FLAGS} )
-  set ( _INSTALL_COMMAND ${CMAKE_COMMAND} -E chdir win32 nmake -f Makefile.msvc install ${_MAKE_FLAGS} )
-else()
-  set ( _CONFIGURE_COMMAND ./configure
-          --prefix=<INSTALL_DIR>
-          $<$<CONFIG:Debug>:--with-debug>
-          --libdir=<INSTALL_DIR>/lib
-          --with-pic
-          --enable-static
-          --without-iconv
-          --without-python
-          --without-lzma
-          CC=${CMAKE_C_COMPILER}
-          CFLAGS=${CMAKE_C_FLAGS}
-          "MAKE=$(MAKE)")
-  set ( _BUILD_COMMAND $(MAKE) all )
-  set ( _INSTALL_COMMAND $(MAKE) install )
-endif()
-
-set( EXTERN ${PROJECT_NAME}-extern )
-include(ExternalProject)
-ExternalProject_Add( ${EXTERN}
-   URL "http://xmlsoft.org/sources/libxml2-${PROJECT_VERSION}.tar.gz"
-   URL_HASH SHA256=${SHA256}
-   UPDATE_COMMAND ""
-   BUILD_IN_SOURCE 1
-   CONFIGURE_COMMAND "${_CONFIGURE_COMMAND}"
-   BUILD_COMMAND "${_BUILD_COMMAND}"
-   INSTALL_COMMAND "${_INSTALL_COMMAND}"
-)
-
-ExternalProject_Get_Property( ${EXTERN} INSTALL_DIR )
-set( INSTALL_DIR ${INSTALL_DIR} )
-
-if (${WIN32})
-  set(CMAKE_STATIC_LIBRARY_PREFIX lib)
-  set(CMAKE_STATIC_LIBRARY_SUFFIX _a$<$<CONFIG:Debug>:d>.lib)
-endif()
-
-add_library(LibXml2_LibXml2 INTERFACE)
-target_include_directories(LibXml2_LibXml2 SYSTEM INTERFACE
-  $<BUILD_INTERFACE:${INSTALL_DIR}/include/libxml2>
-)
-target_link_libraries(LibXml2_LibXml2 INTERFACE
-  ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}xml2${CMAKE_STATIC_LIBRARY_SUFFIX}
-)
-if (${UNIX})
-  target_link_libraries(LibXml2_LibXml2 INTERFACE
-    z
-  )
-endif()
-add_dependencies(LibXml2_LibXml2 ${EXTERN})
-
-add_library(LibXml2::LibXml2 ALIAS LibXml2_LibXml2)
diff --git a/dependencies/xerces-c/CMakeLists.txt b/dependencies/xerces-c/CMakeLists.txt
new file mode 100644
index 0000000..3be40ed
--- /dev/null
+++ b/dependencies/xerces-c/CMakeLists.txt
@@ -0,0 +1,65 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF 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.
+
+project( xerces-c VERSION 3.2.2 LANGUAGES NONE )
+
+set( SHA256 dd6191f8aa256d3b4686b64b0544eea2b450d98b4254996ffdfe630e0c610413)
+set( ${PROJECT_NAME}_EXTERN ${PROJECT_NAME}-extern )
+
+include(GNUInstallDirs)
+include(ExternalProject)
+
+ExternalProject_Add( ${PROJECT_NAME}-extern
+  URL "http://archive.apache.org/dist/xerces/c/3/sources/xerces-c-${PROJECT_VERSION}.tar.gz"
+  URL_HASH SHA256=${SHA256}
+  UPDATE_COMMAND ""
+  CMAKE_ARGS
+    -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}
+    -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
+    -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}
+    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
+    -DCMAKE_INSTALL_PREFIX=<INSTALL_DIR>
+    -DBUILD_SHARED_LIBS=OFF
+    -DCMAKE_POSITION_INDEPENDENT_CODE=ON
+)
+
+ExternalProject_Get_Property( ${PROJECT_NAME}-extern INSTALL_DIR )
+
+if (${WIN32})
+  set(LIBRARY_NAME xerces-c_3$<$<CONFIG:Debug>:D>)
+else()
+  set(LIBRARY_NAME xerces-c-3.2)
+endif()
+
+add_library(${PROJECT_NAME} INTERFACE)
+
+target_include_directories(${PROJECT_NAME} SYSTEM INTERFACE
+  $<BUILD_INTERFACE:${INSTALL_DIR}/include>
+)
+
+target_link_libraries(${PROJECT_NAME} INTERFACE
+  ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${LIBRARY_NAME}${CMAKE_STATIC_LIBRARY_SUFFIX}
+)
+
+if ("Darwin" STREQUAL ${CMAKE_SYSTEM_NAME})
+  target_link_libraries(${PROJECT_NAME} INTERFACE
+    "-framework CoreServices"
+    curl
+  )
+endif()
+
+add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}-extern)
+add_library(XercesC::XercesC ALIAS xerces-c)
+
diff --git a/dist/LICENSE b/dist/LICENSE
index 6772aa9..ef768b8 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -290,30 +290,3 @@ me know.
 
 Douglas C. Schmidt
 
-
----------------------------------------------------------------------------
-The MIT License (http://opensource.org/licenses/MIT)
----------------------------------------------------------------------------
-
-Apache Geode bundles the following files under the MIT License:
-
-  - libxml2 (http://xmlsoft.org),
-    Copyright (C) 1998-2012 Daniel Veillard.  All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.