Replacing master with contents of release/1.10.0
diff --git a/.lgtm.yml b/.lgtm.yml
index c941789..5135970 100644
--- a/.lgtm.yml
+++ b/.lgtm.yml
@@ -4,9 +4,9 @@
       command:
         - mkdir _lgtm_build_dir
         - cd _lgtm_build_dir
-        - wget -O apache-geode.zip http://mirror.transip.net/apache/geode/1.7.0/apache-geode-1.7.0.zip
-        - unzip apache-geode.zip
-        - cmake -DGEODE_ROOT="`pwd`/apache-geode-1.7.0" ..
+        - wget -O apache-geode.tgz http://mirror.transip.net/apache/geode/1.9.0/apache-geode-1.9.0.tgz
+        - tar xzf apache-geode.tgz
+        - cmake -DGEODE_ROOT="`pwd`/apache-geode-1.9.0" ..
         - cd dependencies && cmake --build . -- -j2
     index:
       build_command:
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1a059ac..f3dd50c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -183,6 +183,12 @@
   set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
 endif()
 
+include(CheckCXXSymbolExists)
+check_cxx_symbol_exists("PRId8" "cinttypes" HAVE_STDC_FORMAT_MACROS)
+if (NOT HAVE_STDC_FORMAT_MACROS)
+  target_compile_definitions(c++11 INTERFACE __STDC_FORMAT_MACROS)
+endif()
+
 if(CMAKE_CXX_COMPILER_ID MATCHES "SunPro")
   # Force linker to error on undefined symbols in shared libraries
   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -z defs")
@@ -342,6 +348,7 @@
 
 find_package(OpenSSL REQUIRED)
 
+add_subdirectory(tests/javaobject)
 add_subdirectory(dependencies)
 add_subdirectory(openssl-compat)
 add_subdirectory(cppcache)
@@ -351,7 +358,6 @@
 add_subdirectory(templates/security)
 add_subdirectory(docs/api)
 add_subdirectory(examples)
-add_subdirectory(tests/javaobject)
 if (${BUILD_CLI})
   add_subdirectory(clicache)
 endif()
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/integration-test2/FunctionExecutionTest.cs b/clicache/integration-test2/FunctionExecutionTest.cs
index 6688d31..81b4018 100644
--- a/clicache/integration-test2/FunctionExecutionTest.cs
+++ b/clicache/integration-test2/FunctionExecutionTest.cs
@@ -132,5 +132,30 @@
                 Assert.Equal(expectedResultCount, resultList.Count);
             }
         }
+
+    [Fact(Skip = "Waiting for a fix from Geode server.")]
+    public void FunctionReturnsObjectWhichCantBeDeserializedOnServer()
+    {
+      using (var cluster = new Cluster(output, CreateTestCaseDirectoryName(), 1, 2))
+      {
+        Assert.True(cluster.Start());
+        Assert.Equal(0, cluster.Gfsh.create().region()
+            .withName("region")
+            .withType("REPLICATE")
+            .execute());
+        Assert.Equal(0, cluster.Gfsh.deploy()
+            .withJar(Config.JavaobjectJarPath)
+            .execute());
+
+        var cache = cluster.CreateCache();
+        var pool = cache.GetPoolFactory().AddLocator("localhost", 10334).Create("pool");
+        var region = cache.CreateRegionFactory(RegionShortcut.PROXY)
+            .SetPoolName("pool")
+            .Create<object, object>("region");
+
+        var exc = Client.FunctionService<List<object>>.OnRegion<object, object>(region);
+        Assert.Throws<FunctionExecutionException>(() => exc.Execute("executeFunction_SendObjectWhichCantBeDeserialized"));
+      }
     }
+  }
 }
diff --git a/clicache/src/Cache.cpp b/clicache/src/Cache.cpp
index 9c133fd..622ff85 100644
--- a/clicache/src/Cache.cpp
+++ b/clicache/src/Cache.cpp
@@ -99,8 +99,7 @@
         // TODO shared_ptr this should be checking the return type for which tx mgr
         try
         {
-          auto nativeptr = std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            m_nativeptr->get()->getCacheTransactionManager());
+          auto nativeptr = m_nativeptr->get()->getCacheTransactionManager();
           return Apache::Geode::Client::CacheTransactionManager::Create(nativeptr.get());
         }
         finally
diff --git a/clicache/src/Cache.hpp b/clicache/src/Cache.hpp
index 8766d62..495ecff 100644
--- a/clicache/src/Cache.hpp
+++ b/clicache/src/Cache.hpp
@@ -218,7 +218,7 @@
         /// Returns the instance of <see cref="RegionFactory" /> to create the region
         /// </summary>
         /// <remarks>
-        /// Pass the <see cref="RegionShortcut" /> to set the deafult region attributes
+        /// Pass the <see cref="RegionShortcut" /> to set the default region attributes
         /// </remarks>
         /// <param name="regionShortcut">the regionShortcut to set the default region attributes</param>
         /// <returns>Instance of RegionFactory</returns>
@@ -228,7 +228,7 @@
         /// Returns the instance of <see cref="IRegionService" /> to do the operation on Cache with different Credential.
         /// </summary>
         /// <remarks>
-        /// Deafault pool should be in multiuser mode <see cref="CacheFactory.SetMultiuserAuthentication" />
+        /// Default pool should be in multiuser mode <see cref="CacheFactory.SetMultiuserAuthentication" />
         /// </remarks>
         /// <param name="credentials">the user Credentials.</param>
         /// <returns>Instance of IRegionService</returns>
@@ -238,7 +238,7 @@
         /// Returns the instance of <see cref="IRegionService" /> to do the operation on Cache with different Credential.
         /// </summary>
         /// <remarks>
-        /// Deafault pool should be in multiuser mode <see cref="CacheFactory.SetMultiuserAuthentication" />
+        /// Default pool should be in multiuser mode <see cref="CacheFactory.SetMultiuserAuthentication" />
         /// </remarks>
         /// <param name="credentials">the user Credentials.</param>
         /// <param name="poolName">Pool, which is in multiuser mode.</param>
diff --git a/clicache/src/CacheTransactionManager.hpp b/clicache/src/CacheTransactionManager.hpp
index bddb407..00f2dbf 100644
--- a/clicache/src/CacheTransactionManager.hpp
+++ b/clicache/src/CacheTransactionManager.hpp
@@ -21,7 +21,6 @@
 #include "geode_defs.hpp"
 #include "begin_native.hpp"
 #include <geode/CacheTransactionManager.hpp>
-#include "InternalCacheTransactionManager2PC.hpp"
 #include "end_native.hpp"
 #include "native_shared_ptr.hpp"
 #include "TransactionId.hpp"
@@ -204,7 +203,7 @@
 
       internal:
 
-        inline static CacheTransactionManager^ Create(native::InternalCacheTransactionManager2PC* nativeptr )
+        inline static CacheTransactionManager^ Create(native::CacheTransactionManager* nativeptr )
         {
           return ( nativeptr != nullptr ?
             gcnew CacheTransactionManager( nativeptr ) : nullptr );
@@ -217,12 +216,12 @@
         /// Private constructor to wrap a native object pointer
         /// </summary>
         /// <param name="nativeptr">The native object pointer</param>
-        inline CacheTransactionManager(native::InternalCacheTransactionManager2PC* nativeptr )
+        inline CacheTransactionManager(native::CacheTransactionManager* nativeptr )
           : m_nativeptr(nativeptr)
         {
         }
 
-        native::InternalCacheTransactionManager2PC* m_nativeptr;
+        native::CacheTransactionManager* m_nativeptr;
       };
     }  // namespace Client
   }  // namespace Geode
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 @@
         _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/clicache/src/IRegion.hpp b/clicache/src/IRegion.hpp
index c137420..b8741bd 100644
--- a/clicache/src/IRegion.hpp
+++ b/clicache/src/IRegion.hpp
@@ -104,7 +104,7 @@
           /// This property is applicable to local as well as distributed region.
           /// For local region instance - Puts/Gets a new value into an entry in this region in the local cache only.
           /// For distributed region instance - Puts/Gets a new value into an entry in this region
-          /// and this operation is propogated to the Geode cache server to which it is connected with.
+          /// and this operation is propogated to the Geode cache server to which it is connected.
           /// </remarks>
           /// <param name="key">
           /// The key of the element to get or set.
@@ -487,7 +487,7 @@
           /// <para>
           /// For local region instance - removes the value with the specified key in the local cache only.
           /// For distributed region instance - destroy is propogated to the Geode cache server
-          /// to which it is connected with.          
+          /// to which it is connected.          
           /// </para>
           /// <para>
           /// Does not update any <c>CacheStatistics</c>.
@@ -679,7 +679,7 @@
           /// from this region.
           /// </para>
           /// <para>
-          /// The Remove is propogated to the Geode cache server to which it is connected with.
+          /// The Remove is propogated to the Geode cache server to which it is connected.
           /// </para>
           /// <para>
           /// Does not update any <c>CacheStatistics</c>.
@@ -727,7 +727,7 @@
           /// from this region.
           /// </para>
           /// <para>
-          /// The Remove is propogated to the Geode cache server to which it is connected with.
+          /// The Remove is propogated to the Geode cache server to which it is connected.
           /// </para>
           /// <para>
           /// Does not update any <c>CacheStatistics</c>.
@@ -845,13 +845,13 @@
           /// <para>
           /// If there is already an entry associated with the specified key in
           /// this region, the entry's previous value is overwritten.
-          /// The new put value is propogated to the java server to which it is connected with.
+          /// The new put value is propogated to the java server to which it is connected.
           /// Put is intended for very simple caching situations. In general
           /// it is better to create a <c>ICacheLoader</c> object and allow the
           /// cache to manage the creation and loading of objects.
           /// For local region instance - Puts a new value into an entry in this region in the local cache only.
           /// For distributed region instance - Puts a new value into an entry in this region
-          /// and this operation is propogated to the Geode cache server to which it is connected with.
+          /// and this operation is propogated to the Geode cache server to which it is connected.
           /// </para><para>
           /// Updates the <see cref="CacheStatistics.LastAccessedTime" /> and
           /// <see cref="CacheStatistics.LastModifiedTime" /> for this region and the entry.
@@ -903,21 +903,19 @@
           void Put(TKey key, TValue value, Object^ callbackArg);
 
           /// <summary>
-          /// Puts a new value into an entry in this region with the specified key,
-          /// passing the callback argument to any cache writers and cache listeners
-          /// that are invoked in the operation.
+          /// Puts a new value into an entry in this region with the specified key.
           /// </summary>
           /// <remarks>
           /// <para>
           /// If there is already an entry associated with the specified key in
           /// this region, the entry's previous value is overwritten.
-          /// The new put value is propogated to the java server to which it is connected with.
+          /// The new put value is propogated to the java server to which it is connected.
           /// Put is intended for very simple caching situations. In general
           /// it is better to create a <c>ICacheLoader</c> object and allow the
           /// cache to manage the creation and loading of objects.
           /// For local region instance - Puts a new value into an entry in this region in the local cache only.
           /// For distributed region instance - Puts a new value into an entry in this region
-          /// and this operation is propogated to the Geode cache server to which it is connected with.
+          /// and this operation is propogated to the Geode cache server to which it is connected.
           /// </para><para>
           /// Updates the <see cref="CacheStatistics.LastAccessedTime" /> and
           /// <see cref="CacheStatistics.LastModifiedTime" /> for this region and the entry.
@@ -930,7 +928,7 @@
           /// </para>
           /// </remarks>
           /// <param name="key">
-          /// a key object associated with the value to be put into this region.
+          /// a key object associated with the value to be put into this region
           /// </param>
           /// <param name="value">the value to be put into this region</param>
           /// <exception cref="IllegalArgumentException">
@@ -1096,7 +1094,7 @@
           /// and the entries in it will still exist.
           /// For local region instance - invalidates this region without distributing to other caches.
           /// For distributed region instance - Invalidates this region and this 
-          /// operation is propogated to the Geode cache server to which it is connected with.
+          /// operation is propogated to the Geode cache server to which it is connected.
           /// </para>          
           /// <para>
           /// To remove all the
@@ -1132,7 +1130,7 @@
           /// and the entries in it will still exist.
           /// For local region instance - invalidates this region without distributing to other caches.
           /// For distributed region instance - Invalidates this region and this 
-          /// operation is propogated to the Geode cache server to which it is connected with.
+          /// operation is propogated to the Geode cache server to which it is connected.
           /// </para>
           /// <para>
           /// To remove all the
@@ -1174,7 +1172,7 @@
           /// server region.
           /// For local region instance - destroys the whole local region only
           /// For distributed region instance - destroys the whole local region and this
-          /// operation is also propogated to the Geode cache server to which it is connected with.
+          /// operation is also propogated to the Geode cache server to which it is connected.
           /// </para><para>
           /// Does not update any <c>CacheStatistics</c>.
           /// </para>
@@ -1216,7 +1214,7 @@
           /// server region.
           /// For local region instance - destroys the whole local region only
           /// For distributed region instance - destroys the whole local region and this
-          /// operation is also propogated to the Geode cache server to which it is connected with.
+          /// operation is also propogated to the Geode cache server to which it is connected.
           /// </para><para>
           /// Does not update any <c>CacheStatistics</c>.
           /// </para>
@@ -1261,7 +1259,7 @@
           /// </para>
           /// <para>
           /// For both local & distributed region instaces, invalidate is not propogated to the 
-          /// Geode cache server to which it is connected with.
+          /// Geode cache server to which it is connected.
           /// </para>
           /// <para>
           /// Does not update any <c>CacheStatistics</c>.
@@ -1292,7 +1290,7 @@
           /// </para>
           /// <para>
           /// For both local & distributed region instaces, invalidate is not propogated to the 
-          /// Geode cache server to which it is connected with.
+          /// Geode cache server to which it is connected.
           /// </para>
           /// <para>
           /// Does not update any <c>CacheStatistics</c>.
@@ -1320,7 +1318,7 @@
           /// <para>
           /// If there is already an entry associated with any key in the map in
           /// this region, the entry's previous value is overwritten.
-          /// The new values are propogated to the java server to which it is connected with.
+          /// The new values are propogated to the java server to which it is connected.
           /// PutAll is intended for speed up large amount of put operation into
           /// the same region.
           /// For local region instance - this method is not applicable.
@@ -1365,7 +1363,7 @@
           /// <para>
           /// If there is already an entry associated with any key in the map in
           /// this region, the entry's previous value is overwritten.
-          /// The new values are propogated to the java server to which it is connected with.
+          /// The new values are propogated to the java server to which it is connected.
           /// PutAll is intended for speed up large amount of put operation into
           /// the same region.
           /// For local region instance - this method is not applicable.
@@ -1417,7 +1415,7 @@
           /// <para>
           /// If there is already an entry associated with any key in the map in
           /// this region, the entry's previous value is overwritten.
-          /// The new values are propogated to the java server to which it is connected with.
+          /// The new values are propogated to the java server to which it is connected.
           /// PutAll is intended for speed up large amount of put operation into
           /// the same region.
           /// For local region instance - this method is not applicable.
diff --git a/clicache/src/PoolFactory.hpp b/clicache/src/PoolFactory.hpp
index f16cf54..e6f703e 100644
--- a/clicache/src/PoolFactory.hpp
+++ b/clicache/src/PoolFactory.hpp
@@ -293,7 +293,7 @@
         /// By default SetPRSingleHopEnabled is true.
         /// </summary>
         /// <remarks>
-        /// The client is aware of location of partitions on servers hosting
+        /// The client is aware of the locations of partitions on servers hosting partitioned regions.
         /// Using this information, the client routes the client cache operations
         /// directly to the server which is hosting the required partition for the
         /// cache operation. 
@@ -361,7 +361,7 @@
         /// for the connections but increases the number of connections the servers see.
         /// If false then connections are returned to the pool as soon
         /// as the operation being done with the connection completes. This allows
-        /// connections to be shared amonst multiple threads keeping the number of
+        /// connections to be shared among multiple threads keeping the number of
         /// connections down.
         /// </remarks>
         PoolFactory^ SetThreadLocalConnections(Boolean enabled);
diff --git a/clicache/src/impl/ManagedString.hpp b/clicache/src/impl/ManagedString.hpp
index 60bd2a9..8945ba9 100644
--- a/clicache/src/impl/ManagedString.hpp
+++ b/clicache/src/impl/ManagedString.hpp
@@ -72,10 +72,6 @@
         {
           System::Runtime::InteropServices::Marshal::FreeHGlobal( m_str );
         }
-#if GF_DEVEL_ASSERTS == 1
-        throw gcnew System::ApplicationException(
-          "Finalizer for ManagedString should not have been called!!" );
-#endif
       }
 
       inline static String^ Get( const char* str )
diff --git a/cppcache/CMakeLists.txt b/cppcache/CMakeLists.txt
index 524e52a..bee0117 100644
--- a/cppcache/CMakeLists.txt
+++ b/cppcache/CMakeLists.txt
@@ -74,7 +74,6 @@
 add_library(_apache-geode INTERFACE)
 
 target_compile_definitions(_apache-geode INTERFACE
-  __STDC_FORMAT_MACROS
   BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED
 )
 
@@ -98,7 +97,7 @@
   Boost::boost
   Boost::filesystem
   Boost::thread
-  LibXml2::LibXml2
+  XercesC::XercesC
 )
 
 if (USE_PCH)
@@ -133,4 +132,4 @@
 
 if (BUILD_BENCHMARKS)
   add_subdirectory(benchmark)
-endif()
\ No newline at end of file
+endif()
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/benchmark/CMakeLists.txt b/cppcache/benchmark/CMakeLists.txt
index 5461abe..146424e 100644
--- a/cppcache/benchmark/CMakeLists.txt
+++ b/cppcache/benchmark/CMakeLists.txt
@@ -16,6 +16,7 @@
 add_executable(cpp-benchmark
   main.cpp
   GeodeHashBM.cpp
+  GeodeLoggingBM.cpp
   )
 
 target_link_libraries(cpp-benchmark
diff --git a/cppcache/benchmark/GeodeLoggingBM.cpp b/cppcache/benchmark/GeodeLoggingBM.cpp
new file mode 100644
index 0000000..ac49e31
--- /dev/null
+++ b/cppcache/benchmark/GeodeLoggingBM.cpp
@@ -0,0 +1,122 @@
+/*
+ * 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 <benchmark/benchmark.h>
+
+#include <array>
+
+#include <boost/filesystem.hpp>
+
+#include <geode/CacheableString.hpp>
+
+#include "geode/util/LogLevel.hpp"
+#include "util/Log.hpp"
+#include "util/string.hpp"
+
+using apache::geode::client::Log;
+using apache::geode::client::LogLevel;
+using apache::geode::client::to_utf16;
+using apache::geode::client::to_utf8;
+using apache::geode::client::internal::geode_hash;
+
+const int STRING_ARRAY_LENGTH = 3;
+
+int g_iteration = 0;
+
+std::array<const char*, STRING_ARRAY_LENGTH> logStrings{
+    "Short test string", "Slightly longer test string",
+    "Very long string: "
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
+    "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"};
+
+void GeodeLogStrings(benchmark::State& state) {
+  int index = g_iteration++ % STRING_ARRAY_LENGTH;
+
+  for (auto _ : state) {
+    Log::debug(logStrings[index]);
+  }
+}
+
+void GeodeLogInts(benchmark::State& state) {
+  std::string intString(std::to_string(g_iteration++));
+  for (auto _ : state) {
+    Log::debug(intString.c_str());
+  }
+}
+
+void GeodeLogCombo(benchmark::State& state) {
+  g_iteration++;
+  std::string comboString = std::string(logStrings[g_iteration % 3]) + " " +
+                            std::to_string(g_iteration);
+  for (auto _ : state) {
+    Log::debug(comboString.c_str());
+  }
+}
+
+template <void T(benchmark::State&)>
+void GeodeLogToConsole(benchmark::State& state) {
+  Log::setLogLevel(LogLevel::All);
+
+  T(state);
+
+  Log::close();
+}
+
+template <void T(benchmark::State&)>
+void GeodeLogToFile(benchmark::State& state) {
+  boost::filesystem::path sourcePath(__FILE__);
+  auto filename = std::string("geode_native_") + sourcePath.stem().string() +
+                  std::to_string(__LINE__) + ".log";
+  boost::filesystem::path logPath(filename);
+
+  Log::init(LogLevel::All, filename.c_str());
+
+  T(state);
+
+  Log::close();
+
+  if (boost::filesystem::exists(logPath)) {
+    boost::filesystem::remove(logPath);
+  }
+}
+
+auto LogStringsToConsole = GeodeLogToConsole<GeodeLogStrings>;
+auto LogIntsToConsole = GeodeLogToConsole<GeodeLogInts>;
+auto LogComboToConsole = GeodeLogToConsole<GeodeLogCombo>;
+
+auto LogStringsToFile = GeodeLogToFile<GeodeLogStrings>;
+auto LogIntsToFile = GeodeLogToFile<GeodeLogInts>;
+auto LogComboToFile = GeodeLogToFile<GeodeLogCombo>;
+
+BENCHMARK(LogStringsToConsole)->Range(8, 8 << 10);
+BENCHMARK(LogIntsToConsole)->Range(8, 8 << 10);
+BENCHMARK(LogComboToConsole)->Range(8, 8 << 10);
+BENCHMARK(LogStringsToFile)->Range(8, 8 << 10);
+BENCHMARK(LogIntsToFile)->Range(8, 8 << 10);
+BENCHMARK(LogComboToFile)->Range(8, 8 << 10);
diff --git a/cppcache/include/geode/CacheTransactionManager.hpp b/cppcache/include/geode/CacheTransactionManager.hpp
index 06ebc08..4fa3ebb 100644
--- a/cppcache/include/geode/CacheTransactionManager.hpp
+++ b/cppcache/include/geode/CacheTransactionManager.hpp
@@ -47,6 +47,38 @@
    */
   virtual void begin() = 0;
 
+  /**
+   * Performs prepare during 2 phase commit completion, for the transaction
+   * associated with the current thread.
+   * Locks of the entries modified in the current transaction on the server
+   * side. If the prepare operation fails due to a conflict it will destroy
+   * the transaction state and throw a {@link CommitConflictException}.
+   * If the prepare operation succeeds, transaction state is set to
+   * prepared state.  When this method completes, the thread is still
+   * associated with a transaction, and is waiting on commit or rollback
+   * operation.
+   *
+   * @throws IllegalStateException if the thread is not associated with a
+   * transaction
+   *
+   * @throws CommitConflictException if the commit operation fails due to
+   * a write conflict.
+   *
+   * @throws TransactionDataNodeHasDepartedException if the node hosting the
+   * transaction data has departed. This is only relevant for transaction that
+   * involve PartitionedRegions.
+   *
+   * @throws TransactionDataNotColocatedException if at commit time, the data
+   * involved in the transaction has moved away from the transaction hosting
+   * node. This can only happen if rebalancing/recovery happens during a
+   * transaction that involves a PartitionedRegion.
+   *
+   * @throws TransactionInDoubtException when Geode cannot tell which nodes
+   * have applied the transaction and which have not. This only occurs if nodes
+   * fail mid-commit, and only then in very rare circumstances.
+   */
+  virtual void prepare() = 0;
+
   /** Commit the transaction associated with the current thread. If
    *  the commit operation fails due to a conflict it will destroy
    *  the transaction state and throw a {@link
diff --git a/cppcache/include/geode/CacheableFileName.hpp b/cppcache/include/geode/CacheableFileName.hpp
index 38cb037..28da01b 100644
--- a/cppcache/include/geode/CacheableFileName.hpp
+++ b/cppcache/include/geode/CacheableFileName.hpp
@@ -44,10 +44,10 @@
 
 class APACHE_GEODE_EXPORT CacheableFileName : public CacheableString {
  public:
-  inline CacheableFileName() = default;
-  inline explicit CacheableFileName(const std::string& value)
+  CacheableFileName() = default;
+  explicit CacheableFileName(const std::string& value)
       : CacheableString(value) {}
-  inline explicit CacheableFileName(std::string&& value)
+  explicit CacheableFileName(std::string&& value)
       : CacheableString(std::move(value)) {}
   ~CacheableFileName() noexcept override = default;
   void operator=(const CacheableFileName& other) = delete;
diff --git a/cppcache/include/geode/ExceptionTypes.hpp b/cppcache/include/geode/ExceptionTypes.hpp
index 9f5a48b..c3fb370 100644
--- a/cppcache/include/geode/ExceptionTypes.hpp
+++ b/cppcache/include/geode/ExceptionTypes.hpp
@@ -812,6 +812,18 @@
   }
 };
 
+/**
+ *@brief Thrown when an error is encountered during an SSL operation.
+ **/
+class APACHE_GEODE_EXPORT SslException : public Exception {
+ public:
+  using Exception::Exception;
+  ~SslException() noexcept override {}
+  std::string getName() const override {
+    return "apache::geode::client::SslException";
+  }
+};
+
 }  // namespace client
 }  // namespace geode
 }  // namespace apache
diff --git a/cppcache/include/geode/PdxInstance.hpp b/cppcache/include/geode/PdxInstance.hpp
index 64c345d..ecf0430 100644
--- a/cppcache/include/geode/PdxInstance.hpp
+++ b/cppcache/include/geode/PdxInstance.hpp
@@ -35,17 +35,17 @@
  * deserializing the PDX. Preventing deserialization saves time
  * and memory.
  * The PdxInstance implementation
- * is a light weight wrapper that simply refers to the raw bytes of the PDX
+ * is a lightweight wrapper that simply refers to the raw bytes of the PDX
  * that are kept in the cache.
  * Applications can choose to access PdxInstances instead of C++ objects by
  * configuring the Cache to prefer PDX instances during deserialization.
  * This can be done in <code>cache.xml</code> by setting the attribute
  * <code>read-serialized</code>
- * to true on the <code>pdx</code> element. Or it can be done programmatically
- * using
+ * to true on the <code>pdx</code> element, or it can be done programmatically
+ * using the
  * {@link CacheFactory#setPdxReadSerialized(boolean) setPdxReadSerialized}
  * method. Once this preference is configured, then any time deserialization of
- * a PDX is done it will deserialize into a PdxInstance. PdxInstance are
+ * a PDX is done it will deserialize into a PdxInstance. PdxInstances are
  * immutable. If you want to change one call {@link #createWriter}.
  */
 class APACHE_GEODE_EXPORT PdxInstance : public PdxSerializable {
@@ -76,13 +76,13 @@
   virtual bool hasField(const std::string& fieldname) = 0;
 
   /**
-   * Reads the named field and set its value in std::shared_ptr<Cacheable> type
-   * out param. std::shared_ptr<Cacheable> type is corresponding to java object
+   * Reads the named field and sets its value in std::shared_ptr<Cacheable> type
+   * out param. std::shared_ptr<Cacheable> type corresponds to the Java object
    * type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with std::shared_ptr<Cacheable>
    * type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    * For deserialization C++ Native Client requires the domain class to be
    * registered.
    *
@@ -93,109 +93,109 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in bool type out param.
-   * bool type is corresponding to java boolean type.
+   * Reads the named field and sets its value in bool type out param.
+   * bool type corresponds to the Java boolean type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with bool type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual bool getBooleanField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in signed char type out param.
-   * signed char type is corresponding to java byte type.
+   * Reads the named field and sets its value in signed char type out param.
+   * signed char type corresponds to the Java byte type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with signed char type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual int8_t getByteField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in int16_t type out param.
-   * int16_t type is corresponding to java short type.
+   * Reads the named field and sets its value in int16_t type out param.
+   * int16_t type corresponds to the Java short type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with int16_t type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual int16_t getShortField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in int32_t type out param.
-   * int32_t type is corresponding to java int type.
+   * Reads the named field and sets its value in int32_t type out param.
+   * int32_t type corresponds to the Java int type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with int32_t type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    */
   virtual int32_t getIntField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in int64_t type out param.
-   * int64_t type is corresponding to java long type.
+   * Reads the named field and sets its value in int64_t type out param.
+   * int64_t type corresponds to the Java long type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with int64_t type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual int64_t getLongField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in float type out param.
-   * float type is corresponding to java float type.
+   * Reads the named field and sets its value in float type out param.
+   * float type corresponds to the Java float type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with float type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual float getFloatField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in double type out param.
-   * double type is corresponding to java double type.
+   * Reads the named field and sets its value in double type out param.
+   * double type corresponds to the Java double type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with double type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual double getDoubleField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in char type out param.
-   * char type is corresponding to java char type.
+   * Reads the named field and sets its value in char type out param.
+   * char type corresponds to the Java char type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with char type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual char16_t getCharField(const std::string& fieldName) const = 0;
 
   /**
-   * Reads the named field and set its value in std::string type out param.
-   * std::string type is corresponding to java String type.
+   * Reads the named field and sets its value in std::string type out param.
+   * std::string type corresponds to the Java String type.
    * @param fieldname name of the field to read
    * @return string value for field.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
   virtual std::string getStringField(const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in bool array type out param.
-   * bool* type is corresponding to java boolean[] type.
+   * Reads the named field and sets its value in bool array type out param.
+   * bool* type corresponds to the Java boolean[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with bool array type.
    * @param length length is set with number of bool elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -203,12 +203,12 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in signed char array type out
-   * param. int8_t* type is corresponding to java byte[] type.
+   * Reads the named field and sets its value in signed char array type out
+   * param. int8_t* type corresponds to the Java byte[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with int8_t array type.
    * @param length length is set with number of int8_t elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -216,12 +216,12 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in int16_t array type out param.
-   * int16_t* type is corresponding to java short[] type.
+   * Reads the named field and sets its value in int16_t array type out param.
+   * int16_t* type corresponds to the Java short[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with int16_t array type.
    * @param length length is set with number of int16_t elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -229,12 +229,12 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in int32_t array type out param.
-   * int32_t* type is corresponding to java int[] type.
+   * Reads the named field and sets its value in int32_t array type out param.
+   * int32_t* type corresponds to the Java int[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with int32_t array type.
    * @param length length is set with number of int32_t elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -242,12 +242,12 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in int64_t array type out param.
-   * int64_t* type is corresponding to java long[] type.
+   * Reads the named field and sets its value in int64_t array type out param.
+   * int64_t* type corresponds to the Java long[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with int64_t array type.
    * @param length length is set with number of int64_t elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -255,12 +255,12 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in float array type out param.
-   * float* type is corresponding to java float[] type.
+   * Reads the named field and sets its value in float array type out param.
+   * float* type corresponds to the Java float[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with float array type.
    * @param length length is set with number of float elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -268,12 +268,12 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in double array type out param.
-   * double* type is corresponding to java double[] type.
+   * Reads the named field and sets its value in double array type out param.
+   * double* type corresponds to the Java double[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with double array type.
    * @param length length is set with number of double elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -282,12 +282,12 @@
 
   // charArray
   /**
-   * Reads the named field and set its value in char array type out param.
-   * char16_t* type is corresponding to java char[] type.
+   * Reads the named field and sets its value in char array type out param.
+   * char16_t* type corresponds to the Java char[] type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with char array type.
    * @param length length is set with number of char16_t* elements.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -296,9 +296,9 @@
 
   /**
    * Reads the named field as a string array.
-   * std::vector<std::string> type is corresponding to java String[] type.
+   * std::vector<std::string> type corresponds to the Java String[] type.
    * @param fieldname name of the field to read
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -306,13 +306,13 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in std::shared_ptr<CacheableDate>
+   * Reads the named field and sets its value in std::shared_ptr<CacheableDate>
    * type out param. std::shared_ptr<CacheableDate> type is corresponding to
    * java Java.util.date type.
    * @param fieldname name of the field to read
    * @param value value of the field to be set with
    * std::shared_ptr<CacheableDate> type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -320,14 +320,14 @@
       const std::string& fieldname) const = 0;
 
   /**
-   * Reads the named field and set its value in array of byte arrays type out
+   * Reads the named field and sets its value in array of byte arrays type out
    * param.
-   * int8_t** type is corresponding to java byte[][] type.
+   * int8_t** type corresponds to the Java byte[][] type.
    * @param fieldname name of the field to read.
    * @param value value of the field to be set with array of byte arrays type.
    * @param arrayLength arrayLength is set to the number of byte arrays.
    * @param elementLength elementLength is set to individual byte array lengths.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see PdxInstance#hasField
    */
@@ -336,15 +336,15 @@
                         int32_t*& elementLength) const = 0;
 
   /**
-   * Reads the named field and set its value in
+   * Reads the named field and sets its value in
    * std::shared_ptr<CacheableObjectArray> type out param. For deserialization
    * C++ Native Client requires the domain class to be registered.
-   * std::shared_ptr<CacheableObjectArray> type is corresponding to java
+   * std::shared_ptr<CacheableObjectArray> type corresponds to the Java
    * Object[] type.
    * @param fieldname name of the field to read.
    * @param value value of the field to be set with
    * std::shared_ptr<CacheableObjectArray> type.
-   * @throws IllegalStateException if PdxInstance doesn't has the named field.
+   * @throws IllegalStateException if PdxInstance doesn't have the named field.
    *
    * @see serializationRegistry->addPdxType
    * @see PdxInstance#hasField
@@ -473,7 +473,7 @@
 
   /**
    * @brief Deserialize this object. This is an internal method.
-   * @param PdxReader to Deserialize the PDX object
+   * @param PdxReader to deserialize the PDX object
    */
   virtual void fromData(PdxReader& input) override = 0;
 
diff --git a/cppcache/include/geode/PdxInstanceFactory.hpp b/cppcache/include/geode/PdxInstanceFactory.hpp
index b25e135..b6cb5ed 100644
--- a/cppcache/include/geode/PdxInstanceFactory.hpp
+++ b/cppcache/include/geode/PdxInstanceFactory.hpp
@@ -43,7 +43,7 @@
  * Call the write methods to populate the field data and then call {@link
  * #create}
  * to produce an actual instance that contains the data.
- * To create a factory call {@link Cache#createPdxInstanceFactory}
+ * To create a factory call {@link Cache#createPdxInstanceFactory}.
  * A factory can only create a single instance. To create multiple instances
  * create
  * multiple factories or use {@link PdxInstance#createWriter} to create
diff --git a/cppcache/include/geode/PdxReader.hpp b/cppcache/include/geode/PdxReader.hpp
index 302820c..2b4d451 100644
--- a/cppcache/include/geode/PdxReader.hpp
+++ b/cppcache/include/geode/PdxReader.hpp
@@ -72,7 +72,7 @@
    * <p>C++ char16_t is mapped to Java char</p>
    * @param fieldName name of the field to read.
    * @return value of type wchar_t.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -83,7 +83,7 @@
    * <p>C++ bool is mapped to Java boolean</p>
    * @param fieldName name of the field to read
    * @return value of type bool.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -94,7 +94,7 @@
    * <p>C++ int8_t is mapped to Java byte</p>
    * @param fieldName name of the field to read
    * @return value of type int8_t.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -105,7 +105,7 @@
    * <p>C++ int16_t is mapped to Java short</p>
    * @param fieldName name of the field to read
    * @return value of type int16_t.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -116,7 +116,7 @@
    * <p>C++ int32_t is mapped to Java int</p>
    * @param fieldName name of the field to read
    * @return value of type int32_t.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -127,7 +127,7 @@
    * <p>C++ int64_t is mapped to Java long</p>
    * @param fieldName name of the field to read
    * @return value of type int64_t.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -138,7 +138,7 @@
    * <p>C++ float is mapped to Java float</p>
    * @param fieldName name of the field to read
    * @return value of type float.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -149,7 +149,7 @@
    * <p>C++ double is mapped to Java double</p>
    * @param fieldName name of the field to read
    * @return value of type double.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -161,7 +161,7 @@
    * @param fieldName name of the field to read
    * @return value of type std::string*. Refer to the class description for
    *         how to free the return value.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -172,7 +172,7 @@
    * <p>C++ std::shared_ptr<Cacheable> is mapped to Java object</p>
    * @param fieldName name of the field to read
    * @return value of type std::shared_ptr<Cacheable>.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -185,7 +185,7 @@
    * @param fieldName name of the field to read
    * @param length length is set with number of char16_t elements.
    * @return value of type char16_t*.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -196,7 +196,7 @@
    * <p>C++ bool* is mapped to Java boolean[]</p>
    * @param fieldName name of the field to read
    * @param length length is set with number of bool elements.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -208,7 +208,7 @@
    * @param fieldName name of the field to read
    * @param length length is set with number of int8_t elements
    * @return value of type int8_t*.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -221,7 +221,7 @@
    * @param fieldName name of the field to read
    * @param length length is set with number of int16_t elements
    * @return value of type int16_t*.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -234,7 +234,7 @@
    * @param fieldName name of the field to read
    * @param length length is set with number of int32_t elements
    * @return value of type int32_t*.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -247,7 +247,7 @@
    * @param fieldName name of the field to read
    * @param length length is set with number of int64_t elements
    * @return value of type int64_t*.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -259,7 +259,7 @@
    * @param fieldName name of the field to read
    * @param length length is set with number of float elements
    * @return value of type float*.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -271,7 +271,7 @@
    * @param fieldName name of the field to read
    * @param length length is set with number of double elements
    * @return value of type double*.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -283,7 +283,7 @@
    * @param fieldName name of the field to read
    * @return value of type std::vector<std::string>. Refer to the class
    * description for how to free the return value.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -296,7 +296,7 @@
    * to Java Object[].
    * @param fieldName name of the field to read
    * @return value of type std::shared_ptr<CacheableObjectArray>.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -312,7 +312,7 @@
    * @param elementLength elementLength is set with the length value of
    * individual byte arrays.
    * @return value of type int8_t**.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
@@ -326,7 +326,7 @@
    * Java Date</p>
    * @param fieldName name of the field to read
    * @return value of type std::shared_ptr<CacheableDate>.
-   * @throws IllegalStateException if PdxReader doesn't has the named field.
+   * @throws IllegalStateException if PdxReader doesn't have the named field.
    *
    * @see PdxReader#hasField
    */
diff --git a/cppcache/include/geode/PdxSerializable.hpp b/cppcache/include/geode/PdxSerializable.hpp
index 7f19a66..3cf1842 100644
--- a/cppcache/include/geode/PdxSerializable.hpp
+++ b/cppcache/include/geode/PdxSerializable.hpp
@@ -49,14 +49,14 @@
   int32_t hashcode() const override;
 
   /**
-   *@brief serialize this object in geode PDX format
+   *@brief Serialize this object in Geode PDX format
    *@param PdxWriter to serialize the PDX object
    **/
   virtual void toData(PdxWriter& output) const = 0;
 
   /**
    *@brief Deserialize this object
-   *@param PdxReader to Deserialize the PDX object
+   *@param PdxReader to deserialize the PDX object
    **/
   virtual void fromData(PdxReader& input) = 0;
 
diff --git a/cppcache/include/geode/PdxSerializer.hpp b/cppcache/include/geode/PdxSerializer.hpp
index 64d1de5..0820b41 100644
--- a/cppcache/include/geode/PdxSerializer.hpp
+++ b/cppcache/include/geode/PdxSerializer.hpp
@@ -29,8 +29,8 @@
 namespace client {
 
 /**
- * Function pointer type which takes a void pointer to an instance of a user
- * object and class name to return the size of the user object.
+ * Function pointer type that takes a void pointer to an instance of a user
+ * object and a class name to return the size of the user object.
  */
 using UserObjectSizer = std::function<size_t(const std::shared_ptr<const void>&,
                                              const std::string&)>;
@@ -40,8 +40,8 @@
  * serialized and deserialized as PDXs without modification
  * of the domain class.
  * A domain class should register function {@link
- * Serializable::registerPdxSerializer} to create new
- * instance of type for de-serilization.
+ * Serializable::registerPdxSerializer} to create a new
+ * instance of type for de-serialization.
  */
 class APACHE_GEODE_EXPORT PdxSerializer {
  public:
@@ -52,15 +52,15 @@
   /**
    * Deserialize this object.
    *
-   * @param className the class name whose object need to de-serialize
+   * @param className the class name whose object needs to be de-serialized
    * @param pr the PdxReader stream to use for reading the object data
    */
   virtual std::shared_ptr<void> fromData(const std::string& className,
                                          PdxReader& pdxReader) = 0;
 
   /**
-   * Serializes this object in geode PDX format.
-   * @param userObject the object which need to serialize
+   * Serializes this object in Geode PDX format.
+   * @param userObject the object which needs to be serialized
    * @param pw the PdxWriter object to use for serializing the object
    */
   virtual bool toData(const std::shared_ptr<const void>& userObject,
diff --git a/cppcache/include/geode/Pool.hpp b/cppcache/include/geode/Pool.hpp
index 748bb43..85c11b0 100644
--- a/cppcache/include/geode/Pool.hpp
+++ b/cppcache/include/geode/Pool.hpp
@@ -182,7 +182,7 @@
   bool getMultiuserAuthentication() const;
 
   /**
-   * Returns true if single-hop optimisation is enabled on this pool.
+   * Returns true if single-hop optimization is enabled on this pool.
    * @see PoolFactory#setPRSingleHopEnabled
    */
   bool getPRSingleHopEnabled() const;
diff --git a/cppcache/include/geode/PoolFactory.hpp b/cppcache/include/geode/PoolFactory.hpp
index e8510a3..195e28d 100644
--- a/cppcache/include/geode/PoolFactory.hpp
+++ b/cppcache/include/geode/PoolFactory.hpp
@@ -108,7 +108,7 @@
   static const int DEFAULT_MAX_CONNECTIONS = -1;
 
   /**
-   * The default amount of time in to wait for a connection to become idle.
+   * The default amount of time to wait for a connection to become idle.
    * <p>Current value: <code>5s</code>.
    */
   static const std::chrono::milliseconds DEFAULT_IDLE_TIMEOUT;
@@ -121,7 +121,7 @@
   static const int DEFAULT_RETRY_ATTEMPTS = -1;
 
   /**
-   * The default frequenc, to ping servers.
+   * The default frequency, to ping servers.
    * <p>Current value: <code>10s</code>.
    */
   static const std::chrono::milliseconds DEFAULT_PING_INTERVAL;
@@ -186,7 +186,7 @@
   static constexpr bool DEFAULT_MULTIUSER_SECURE_MODE = false;
 
   /**
-   * The default value for whether to have single hop optimisations enabled.
+   * The default value for whether to have single hop optimizations enabled.
    * <p>Current value: <code>true</code>.
    */
   static constexpr bool DEFAULT_PR_SINGLE_HOP_ENABLED = true;
@@ -254,7 +254,7 @@
    * see.
    * <p>If <code>false</code> then connections are returned to the pool as soon
    * as the operation being done with the connection completes. This allows
-   * connections to be shared amonst multiple threads keeping the number of
+   * connections to be shared among multiple threads keeping the number of
    * connections down.
    *
    * @param threadLocalConnections if <code>true</code> then enable thread local
@@ -485,7 +485,7 @@
    * Sets whether Pool is in multi user secure mode.
    * If its in multiuser mode then app needs to get RegionService instance of
    * Cache.
-   * Deafult value is false.
+   * Default value is false.
    * @return a reference to <code>this</code>
    */
   PoolFactory& setMultiuserAuthentication(bool multiuserAuthentication);
@@ -510,23 +510,23 @@
   std::shared_ptr<Pool> create(std::string name);
 
   /**
-   * By default setPRSingleHopEnabled is true<br>
-   * The client is aware of location of partitions on servers hosting
-   * {@link Region}s.
-   * Using this information, the client routes the client cache operations
+   * By default setPRSingleHopEnabled is true.<br>
+   * The client is aware of the locations of partitions on servers hosting
+   * partitioned regions.
+   * Using this information, the client routes client cache operations
    * directly to the server which is hosting the required partition for the
    * cache operation.
    * If setPRSingleHopEnabled is false the client can do an extra hop on servers
    * to go to the required partition for that cache operation.
-   * The setPRSingleHopEnabled avoids extra hops only for following cache
-   * operations:<br>
+   * The setPRSingleHopEnabled setting avoids extra hops only for the following
+   * cache operations:<br>
    * 1. {@link Region#put(Object, Object)}<br>
    * 2. {@link Region#get(Object)}<br>
    * 3. {@link Region#destroy(Object)}<br>
    * If true, works best when {@link PoolFactory#setMaxConnections(int)} is set
    * to -1.
-   * @param name is boolean whether PR Single Hop optimization is enabled or
-   * not.
+   * @param enabled is a boolean indicating whether PR Single Hop optimization
+   * should be enabled or not.
    * @return a reference to <code>this</code>
    */
   PoolFactory& setPRSingleHopEnabled(bool enabled);
diff --git a/cppcache/include/geode/SystemProperties.hpp b/cppcache/include/geode/SystemProperties.hpp
index 2f22c2b..f00d6aa 100644
--- a/cppcache/include/geode/SystemProperties.hpp
+++ b/cppcache/include/geode/SystemProperties.hpp
@@ -269,7 +269,7 @@
 
   /**
    * Returns true if app wants to clear pdx type ids when client disconnect.
-   * deafult is false.
+   * default is false.
    */
   bool onClientDisconnectClearPdxTypeIds() const {
     return m_onClientDisconnectClearPdxTypeIds;
diff --git a/cppcache/integration-test/ThinClientTransactions.hpp b/cppcache/integration-test/ThinClientTransactions.hpp
index 0f9e22c..76e13ac 100644
--- a/cppcache/integration-test/ThinClientTransactions.hpp
+++ b/cppcache/integration-test/ThinClientTransactions.hpp
@@ -1002,6 +1002,7 @@
     LOG("StepSix complete.");
   }
 END_TASK_DEFINITION
+
 DUNIT_TASK_DEFINITION(CLIENT1, CreateClient1EntryTwice)
   { createEntryTwice(regionNames[0], CREATE_TWICE_KEY, CREATE_TWICE_VALUE); }
 END_TASK_DEFINITION
diff --git a/cppcache/integration-test/ThinClientTransactionsXA.hpp b/cppcache/integration-test/ThinClientTransactionsXA.hpp
index e52a26f..70b5c4b 100644
--- a/cppcache/integration-test/ThinClientTransactionsXA.hpp
+++ b/cppcache/integration-test/ThinClientTransactionsXA.hpp
@@ -27,7 +27,7 @@
 
 #include <string>
 #include <geode/TransactionId.hpp>
-#include <InternalCacheTransactionManager2PC.hpp>
+#include <geode/CacheTransactionManager.hpp>
 
 #define ROOT_NAME "ThinClientTransactionsXA"
 #define ROOT_SCOPE DISTRIBUTED_ACK
@@ -43,7 +43,7 @@
 using apache::geode::client::EntryExistsException;
 using apache::geode::client::EntryNotFoundException;
 using apache::geode::client::IllegalStateException;
-using apache::geode::client::InternalCacheTransactionManager2PC;
+using apache::geode::client::CacheTransactionManager;
 using apache::geode::client::Properties;
 using apache::geode::client::TransactionException;
 using apache::geode::client::TransactionId;
@@ -384,9 +384,7 @@
     sprintf(buf, " In SuspendTransactionThread");
     LOG(buf);
 
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
 
     txManager->begin();
 
@@ -462,9 +460,7 @@
                      "In ResumeTransactionThread - Key should not have been "
                      "found in region.");
 
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
     if (m_tryResumeWithSleep) {
       THREADERRORCHECK(!txManager->isSuspended(m_suspendedTransaction),
                        "In ResumeTransactionThread - the transaction should "
@@ -580,9 +576,7 @@
 
 DUNIT_TASK_DEFINITION(CLIENT1, SuspendResumeCommit)
   {
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
     auto regPtr0 = getHelper()->getRegion(regionNames[0]);
     ASSERT(regPtr0 != nullptr, "In SuspendResumeCommit - Region not found.");
     auto regPtr1 = getHelper()->getRegion(regionNames[1]);
@@ -665,9 +659,7 @@
 
 DUNIT_TASK_DEFINITION(CLIENT1, SuspendTimeOut)
   {
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
     auto keyPtr4 = CacheableKey::create(keys[4]);
     auto keyPtr5 = CacheableKey::create(keys[5]);
 
@@ -709,9 +701,7 @@
 
 DUNIT_TASK_DEFINITION(CLIENT1, SuspendResumeRollback)
   {
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
     auto keyPtr4 = CacheableKey::create(keys[4]);
     auto keyPtr5 = CacheableKey::create(keys[5]);
     auto keyPtr6 = CacheableKey::create(keys[6]);
@@ -951,9 +941,7 @@
 
 DUNIT_TASK_DEFINITION(CLIENT1, StepThree)
   {
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
     txManager->begin();
     createEntry(regionNames[0], keys[0], vals[0]);
     createEntry(regionNames[1], keys[2], vals[2]);
@@ -967,9 +955,7 @@
   {
     doNetsearch(regionNames[0], keys[0], vals[0]);
     doNetsearch(regionNames[1], keys[2], vals[2]);
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
     txManager->begin();
     createEntry(regionNames[0], keys[1], vals[1]);
     createEntry(regionNames[1], keys[3], vals[3]);
@@ -1016,9 +1002,7 @@
   {
     doNetsearch(regionNames[0], keys[0], vals[0]);
     doNetsearch(regionNames[1], keys[2], vals[2]);
-    auto txManager =
-        std::dynamic_pointer_cast<InternalCacheTransactionManager2PC>(
-            getHelper()->getCache()->getCacheTransactionManager());
+    auto txManager = getHelper()->getCache()->getCacheTransactionManager();
     txManager->begin();
     updateEntry(regionNames[0], keys[1], nvals[1]);
     updateEntry(regionNames[1], keys[3], nvals[3]);
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-test/resources/func_cacheserver1_pool.xml b/cppcache/integration-test/resources/func_cacheserver1_pool.xml
index 34d6e0e..b5fefaa 100755
--- a/cppcache/integration-test/resources/func_cacheserver1_pool.xml
+++ b/cppcache/integration-test/resources/func_cacheserver1_pool.xml
@@ -18,7 +18,8 @@
 <cache 
 	xmlns="http://geode.apache.org/schema/cache" 
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
-	<cache-server port="HOST_PORT1">
+	<!--cache-server host="cod" port="24680" /-->
+	<cache-server port="0">
 		<group>ServerGroup1</group>
 	</cache-server>
 	<pdx read-serialized="true" />
@@ -41,9 +42,6 @@
 			<class-name>javaobject.MultiGetFunction2</class-name>
 		</function>
 		<function>
-			<class-name>javaobject.ThinClientRegionExceptionTest</class-name>
-		</function>
-		<function>
 			<class-name>javaobject.MultiPutFunction</class-name>
 		</function>
 		<function>
diff --git a/cppcache/integration-test/resources/func_cacheserver2_pool.xml b/cppcache/integration-test/resources/func_cacheserver2_pool.xml
index fb1e791..1223c7b 100755
--- a/cppcache/integration-test/resources/func_cacheserver2_pool.xml
+++ b/cppcache/integration-test/resources/func_cacheserver2_pool.xml
@@ -18,7 +18,7 @@
 <cache 
 	xmlns="http://geode.apache.org/schema/cache" 
 	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
-	<cache-server port="HOST_PORT2">
+	<cache-server port="0">
 		<group>ServerGroup1</group>
 	</cache-server>
 	<pdx read-serialized="true" />
@@ -76,9 +76,6 @@
 		<function>
 			<class-name>javaobject.FEOnRegionPrSHOP_OptimizeForWrite</class-name>
 		</function>
-		<function>
-			<class-name>javaobject.ThinClientRegionExceptionTest</class-name>
-		</function>
 	</function-service>
 	<serialization-registration>
 		<instantiator id="5200">
diff --git a/cppcache/integration-test/testSerialization.cpp b/cppcache/integration-test/testSerialization.cpp
index 14b8816..24c4b07 100644
--- a/cppcache/integration-test/testSerialization.cpp
+++ b/cppcache/integration-test/testSerialization.cpp
@@ -15,9 +15,7 @@
  * limitations under the License.
  */
 
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
-
+#include <cinttypes>
 #include <memory>
 
 #include <geode/internal/geode_base.hpp>
diff --git a/cppcache/integration-test/testThinClientBigValue.cpp b/cppcache/integration-test/testThinClientBigValue.cpp
index fc9ad73..5c2ad19 100644
--- a/cppcache/integration-test/testThinClientBigValue.cpp
+++ b/cppcache/integration-test/testThinClientBigValue.cpp
@@ -15,8 +15,7 @@
  * limitations under the License.
  */
 
-#define __STDC_FORMAT_MACROS
-#include <inttypes.h>
+#include <cinttypes>
 
 #include <geode/internal/geode_base.hpp>
 
diff --git a/cppcache/integration-test/testXmlCacheCreationWithPools.cpp b/cppcache/integration-test/testXmlCacheCreationWithPools.cpp
index 81329a5..6a779e6 100644
--- a/cppcache/integration-test/testXmlCacheCreationWithPools.cpp
+++ b/cppcache/integration-test/testXmlCacheCreationWithPools.cpp
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-#include <inttypes.h>
+#include <cinttypes>
 #include <cstdint>
 #include <iostream>
 #include <string>
diff --git a/cppcache/integration/framework/CMakeLists.txt b/cppcache/integration/framework/CMakeLists.txt
index 8aa234c..61fb4a1 100644
--- a/cppcache/integration/framework/CMakeLists.txt
+++ b/cppcache/integration/framework/CMakeLists.txt
@@ -13,19 +13,26 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-configure_file(config.h.in config.h)
+get_target_property(JAVAOBJECT_JAR_PATH javaobject JAR_FILE)
+
+configure_file(TestConfig.cpp.in TestConfig.cpp)
 
 add_library(integration-framework STATIC
-  Gfsh.cpp
-  Gfsh.h
-  Framework.cpp
-  Framework.h
   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
   )
 
+add_dependencies(integration-framework javaobject)
+
 target_compile_definitions(integration-framework
   PUBLIC
     BOOST_ASIO_HAS_MOVE
diff --git a/cppcache/integration/framework/Cluster.cpp b/cppcache/integration/framework/Cluster.cpp
index 21c1bbd..f0907e1 100644
--- a/cppcache/integration/framework/Cluster.cpp
+++ b/cppcache/integration/framework/Cluster.cpp
@@ -43,18 +43,17 @@
       .withMaxHeap("256m")
       .withJmxManagerPort(jmxManagerPort_)
       .withHttpServicePort(0)
-      .execute();
+      .withClasspath(cluster_.getClasspath())
+      .withSecurityManager(cluster_.getSecurityManager())
+      .execute(cluster_.getUser(), cluster_.getPassword());
 
-  //    std::cout << "locator: " << locatorAddress_.port << ": started"
-  //              << std::endl;
   started_ = true;
 }
 
 void Locator::stop() {
   cluster_.getGfsh().stop().locator().withDir(name_).execute();
 
-  //    std::cout << "locator: " << locatorAddress_.port << ": stopped"
-  //              << std::endl;
+//  std::cout << "locator: " << locatorAddress_.port << ": stopped" << std::endl << std::flush;
   started_ = false;
 }
 
@@ -72,22 +71,26 @@
       .withMaxHeap("1g")
       .withLocators(locators_.front().getAddress().address + "[" +
                     std::to_string(locators_.front().getAddress().port) + "]")
+      .withClasspath(cluster_.getClasspath())
+      .withSecurityManager(cluster_.getSecurityManager())
+      .withUser(cluster_.getUser())
+      .withPassword(cluster_.getPassword())
+      .withCacheXMLFile(getCacheXMLFile())
       .execute();
 
-  //    std::cout << "server: " << serverAddress_.port << ": started" <<
-  //    std::endl;
+//  std::cout << "server: " << serverAddress_.port << ": started" << std::endl << std::flush;
+
   started_ = true;
 }
 
 void Server::stop() {
   cluster_.getGfsh().stop().server().withDir(name_).execute();
 
-  //    std::cout << "server: " << serverAddress_.port << ": stopped" <<
-  //    std::endl;
+//  std::cout << "server: " << serverAddress_.port << ": stopped" << std::endl << std::flush;
   started_ = false;
 }
 
-void Cluster::start() {
+void Cluster::start(std::function<void()> extraGfshCommands) {
   locators_.reserve(initialLocators_);
   for (size_t i = 0; i < initialLocators_; i++) {
     locators_.push_back({*this, locators_,
@@ -96,13 +99,20 @@
   }
 
   servers_.reserve(initialServers_);
+  std::string xmlFile;
   for (size_t i = 0; i < initialServers_; i++) {
+    xmlFile = (cacheXMLFiles_.size() == 0) ? "" :
+               cacheXMLFiles_.size() == 1 ? cacheXMLFiles_[1] :
+               cacheXMLFiles_[i];
+
     servers_.push_back(
-        {*this, locators_, name_ + "/server/" + std::to_string(i)});
+      {*this, locators_, name_ + "/server/" + std::to_string(i), xmlFile});
   }
 
   startLocators();
 
+  extraGfshCommands();
+  
   startServers();
 
   //    std::cout << "cluster: " << jmxManagerPort_ << ": started" << std::endl;
diff --git a/cppcache/integration/framework/Cluster.h b/cppcache/integration/framework/Cluster.h
index 99c2ccf..4578437 100644
--- a/cppcache/integration/framework/Cluster.h
+++ b/cppcache/integration/framework/Cluster.h
@@ -23,25 +23,13 @@
 #include <cstdint>
 #include <string>
 
-#include "gtest/gtest.h"
-
 #include <geode/Cache.hpp>
 #include <geode/PoolManager.hpp>
 
 #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"
+#include "gtest/gtest.h"
 
 class Cluster;
 
@@ -115,8 +103,11 @@
 
 class Server {
  public:
-  Server(Cluster &cluster, std::vector<Locator> &locators, std::string name)
-      : cluster_(cluster), locators_(locators), name_(std::move(name)) {
+  Server(Cluster &cluster, std::vector<Locator> &locators, std::string name, std::string xmlFile)
+      : cluster_(cluster),
+        locators_(locators),
+        name_(std::move(name)),
+        xmlFile_(xmlFile) {
     auto hostname = "localhost";
     auto port = static_cast<uint16_t>(0);
     serverAddress_ = ServerAddress{hostname, port};
@@ -124,6 +115,8 @@
     // start();
   }
 
+  std::string getCacheXMLFile() { return xmlFile_; }
+
   ~Server() noexcept {
     try {
       if (started_) {
@@ -140,7 +133,8 @@
         locators_(move.locators_),
         serverAddress_(move.serverAddress_),
         started_(move.started_),
-        name_(move.name_) {
+        name_(move.name_),
+        xmlFile_(move.xmlFile_) {
     move.started_ = false;
   };
   //  Server &operator=(Server &&other) = default;
@@ -158,11 +152,18 @@
   bool started_ = false;
 
   std::string name_;
+  std::string xmlFile_;
 };
 
 using LocatorCount = NamedType<size_t, struct LocatorCountParameter>;
 using ServerCount = NamedType<size_t, struct ServerCountParameter>;
 using Name = NamedType<std::string, struct NameParameter>;
+using Classpath = NamedType<std::string, struct ClasspathParameter>;
+using SecurityManager = NamedType<std::string, struct SecurityManagerParameter>;
+using User = NamedType<std::string, struct UserParameter>;
+using Password = NamedType<std::string, struct PasswordParameter>;
+using CacheXMLFiles =
+    NamedType<std::vector<std::string>, struct CacheXMLFilesParameter>;
 
 class Cluster {
  public:
@@ -174,17 +175,59 @@
                      ::testing::UnitTest::GetInstance()
                          ->current_test_info()
                          ->name()),
-                initialLocators, initialServers){};
+                initialLocators, initialServers) {}
+
+  Cluster(LocatorCount initialLocators, ServerCount initialServers,
+          CacheXMLFiles cacheXMLFiles)
+      : name_(std::string(::testing::UnitTest::GetInstance()
+                              ->current_test_info()
+                              ->test_case_name()) +
+              "/" +
+              ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+        initialLocators_(initialLocators.get()),
+        initialServers_(initialServers.get()),
+        jmxManagerPort_(Framework::getAvailablePort()) {
+    removeServerDirectory();
+    cacheXMLFiles_ = cacheXMLFiles.get();
+  }
 
   Cluster(Name name, LocatorCount initialLocators, ServerCount initialServers)
+      : Cluster(Name(name.get()), Classpath(""), SecurityManager(""), User(""),
+                Password(""), initialLocators, initialServers,
+                CacheXMLFiles({})) {}
+
+  Cluster(Name name, Classpath classpath, SecurityManager securityManager,
+          User user, Password password, LocatorCount initialLocators,
+          ServerCount initialServers, CacheXMLFiles cacheXMLFiles)
       : name_(name.get()),
+        classpath_(classpath.get()),
+        securityManager_(securityManager.get()),
+        user_(user.get()),
+        password_(password.get()),
+        initialLocators_(initialLocators.get()),
+        initialServers_(initialServers.get()) {
+    jmxManagerPort_ = Framework::getAvailablePort();
+    cacheXMLFiles_ = cacheXMLFiles.get();
+
+    removeServerDirectory();
+    start();
+  };
+
+  Cluster(Name name, Classpath classpath, SecurityManager securityManager,
+          User user, Password password, LocatorCount initialLocators,
+          ServerCount initialServers)
+      : name_(name.get()),
+        classpath_(classpath.get()),
+        securityManager_(securityManager.get()),
+        user_(user.get()),
+        password_(password.get()),
         initialLocators_(initialLocators.get()),
         initialServers_(initialServers.get()) {
     jmxManagerPort_ = Framework::getAvailablePort();
 
     removeServerDirectory();
     start();
-  }
+  };
 
   ~Cluster() noexcept {
     try {
@@ -205,7 +248,7 @@
            std::to_string(jmxManagerPort_) + "]";
   }
 
-  void start();
+  void start(std::function<void()> fn = []() {});
 
   void stop();
 
@@ -218,6 +261,12 @@
 
   apache::geode::client::Cache createCache(
       const std::unordered_map<std::string, std::string> &properties) {
+    return createCache(properties, false);
+  }
+
+  apache::geode::client::Cache createCache(
+      const std::unordered_map<std::string, std::string> &properties,
+      bool subscriptionEnabled) {
     using apache::geode::client::CacheFactory;
 
     CacheFactory cacheFactory;
@@ -230,7 +279,9 @@
                      .set("statistic-sampling-enabled", "false")
                      .create();
 
-    auto poolFactory = cache.getPoolManager().createFactory();
+    auto poolFactory =
+        cache.getPoolManager().createFactory().setSubscriptionEnabled(
+            subscriptionEnabled);
     applyLocators(poolFactory);
     poolFactory.create("default");
 
@@ -246,12 +297,27 @@
 
   Gfsh &getGfsh() noexcept { return gfsh_; }
 
-  std::vector<Server>& getServers() {
-    return servers_;
-  }
+  std::vector<Server> &getServers() { return servers_; }
+
+  std::vector<Locator> &getLocators() { return locators_; }
+
+  std::string &getClasspath() { return classpath_; }
+
+  std::string &getSecurityManager() { return securityManager_; }
+
+  std::string &getUser() { return user_; }
+
+  std::string &getPassword() { return password_; }
+
+  std::vector<std::string> &getCacheXMLFiles() { return cacheXMLFiles_; }
 
  private:
   std::string name_;
+  std::string classpath_;
+  std::string securityManager_;
+  std::string user_;
+  std::string password_;
+  std::vector<std::string> cacheXMLFiles_;
 
   size_t initialLocators_;
   std::vector<Locator> locators_;
diff --git a/cppcache/integration/framework/Gfsh.h b/cppcache/integration/framework/Gfsh.h
index 20d9713..7df7ebd 100644
--- a/cppcache/integration/framework/Gfsh.h
+++ b/cppcache/integration/framework/Gfsh.h
@@ -45,6 +45,9 @@
   class Shutdown;
   Shutdown shutdown() { return Shutdown{*this}; }
 
+  class Deploy;
+  Deploy deploy() { return Deploy(*this); }
+
   class Verb {
    public:
    protected:
@@ -55,7 +58,8 @@
   template <class Result>
   class Command {
    public:
-    virtual Result execute() { Result{gfsh_}.parse(gfsh_.execute(command_)); }
+    virtual Result execute(const std::string &user, const std::string &password) { Result{gfsh_}.parse(gfsh_.execute(command_, user, password)); }
+    virtual Result execute() { Result{gfsh_}.parse(gfsh_.execute(command_, "", "")); }
 
    protected:
     Command(Gfsh &gfsh, std::string command)
@@ -118,6 +122,25 @@
         command_ += " --max-heap=" + maxHeap;
         return *this;
       };
+
+      Locator &withClasspath(const std::string classpath) {
+        if (!classpath.empty()) {
+          command_ += " --classpath=" + classpath;
+        }
+        return *this;
+      };
+
+      Locator &withSecurityManager(const std::string securityManager) {
+        if (!securityManager.empty()) {
+          command_ += " --J=-Dgemfire.security-manager=" + securityManager;
+        }
+        return *this;
+      };
+
+      Locator &withConnect(const std::string connect) {
+        command_ += " --connect=" + connect;
+        return *this;
+      };
     };
 
     class Server : public Command<void> {
@@ -127,37 +150,73 @@
       Server &withName(const std::string &name) {
         command_ += " --name=" + name;
         return *this;
-      };
+      }
 
       Server &withDir(const std::string &dir) {
         command_ += " --dir=" + dir;
         return *this;
-      };
+      }
 
       Server &withBindAddress(const std::string &bindAddress) {
         command_ += " --bind-address=" + bindAddress;
         return *this;
-      };
+      }
 
       Server &withPort(uint16_t serverPort) {
         command_ += " --server-port=" + std::to_string(serverPort);
         return *this;
-      };
+      }
 
       Server &withLocators(const std::string locators) {
         command_ += " --locators=" + locators;
         return *this;
-      };
+      }
 
       Server &withLogLevel(const std::string logLevel) {
         command_ += " --log-level=" + logLevel;
         return *this;
-      };
+      }
 
       Server &withMaxHeap(const std::string maxHeap) {
         command_ += " --max-heap=" + maxHeap;
         return *this;
-      };
+      }
+
+      Server &withClasspath(const std::string classpath) {
+        if (!classpath.empty()) {
+          command_ += " --classpath=" + classpath;
+        }
+        return *this;
+      }
+
+      Server &withSecurityManager(const std::string securityManager) {
+        if (!securityManager.empty()) {
+          command_ += " --J=-Dgemfire.security-manager=" + securityManager;
+        }
+        return *this;
+      }
+
+      Server &withUser(const std::string user) {
+        if (!user.empty()) {
+          command_ += " --user=" + user;
+        }
+
+        return *this;
+      }
+
+      Server &withPassword(const std::string password) {
+        if (!password.empty()) {
+          command_ += " --password=" + password;
+        }
+        return *this;
+      }
+
+      Server &withCacheXMLFile(const std::string file) {
+        if (!file.empty()) {
+          command_ += " --cache-xml-file=" + file;
+        }
+        return *this;
+      }
     };
 
    private:
@@ -239,6 +298,16 @@
       command_ += " --jmx-manager=" + jmxManager;
       return *this;
     };
+
+    Connect &withUser(const std::string &user) {
+      command_ += " --user=" + user;
+      return *this;
+    };
+
+    Connect &withPassword(const std::string &password) {
+      command_ += " --password=" + password;
+      return *this;
+    };
   };
 
   class Shutdown : public Command<void> {
@@ -252,13 +321,30 @@
     };
   };
 
+  class Deploy : public Command<void> {
+   public:
+    explicit Deploy(Gfsh &gfsh) : Command{gfsh, "deploy"} {}
+
+    Deploy &jar(const std::string &jarFile) {
+      command_ += " --jars=" + jarFile;
+
+      return *this;
+    }
+  };
+
  protected:
-  virtual void execute(const std::string &command) = 0;
+  virtual void execute(const std::string &command, const std::string &user, const std::string &password) = 0;
 };
 
 template <>
-inline void Gfsh::Command<void>::execute() {
-  gfsh_.execute(command_);
+inline void Gfsh::Command<void>::execute(const std::string &user, const std::string &password) {
+  gfsh_.execute(command_, user, password);
 }
 
+template <>
+inline void Gfsh::Command<void>::execute() {
+  gfsh_.execute(command_, "", "");
+}
+
+
 #endif  // INTEGRATION_TEST_FRAMEWORK_GFSH_H
diff --git a/cppcache/integration/framework/GfshExecute.cpp b/cppcache/integration/framework/GfshExecute.cpp
index 5ae9023..c5e752b 100644
--- a/cppcache/integration/framework/GfshExecute.cpp
+++ b/cppcache/integration/framework/GfshExecute.cpp
@@ -32,7 +32,7 @@
 using boost::process::std_err;
 using boost::process::std_out;
 
-void GfshExecute::execute(const std::string &command) {
+void GfshExecute::execute(const std::string &command, const std::string &user, const std::string &password) {
   BOOST_LOG_TRIVIAL(info) << "Gfsh::execute: " << command;
 
   std::vector<std::string> commands;
@@ -70,7 +70,7 @@
   if (exit_code) {
     throw new GfshExecuteException("gfsh error", exit_code);
   }
-  extractConnectionCommand(command);
+  extractConnectionCommand(command, user, password);
 }
 
 child GfshExecute::executeChild(std::vector<std::string> &commands,
@@ -80,6 +80,37 @@
   // https://github.com/klemens-morgenstern/boost-process/issues/159
   std::lock_guard<std::mutex> guard(g_child_mutex);
 #endif
-  return child(GFSH_EXECUTABLE, args = commands, env, std_out > outStream,
+  return child(getFrameworkString(FrameworkVariable::GfShExecutable), args = commands, env, std_out > outStream,
                std_err > errStream);
 }
+
+void GfshExecute::extractConnectionCommand(const std::string &command, const std::string &user, const std::string &password) {
+  if (starts_with(command, std::string("connect"))) {
+    connection_ = command;
+  } else if (starts_with(command, std::string("start locator"))) {
+    auto jmxManagerHost = std::string("localhost");
+    auto jmxManagerPort = std::string("1099");
+
+    std::regex jmxManagerHostRegex("bind-address=([^\\s]+)");
+    std::smatch jmxManagerHostMatch;
+    if (std::regex_search(command, jmxManagerHostMatch,
+                          jmxManagerHostRegex)) {
+      jmxManagerHost = jmxManagerHostMatch[1];
+    }
+
+    std::regex jmxManagerPortRegex("jmx-manager-port=(\\d+)");
+    std::smatch jmxManagerPortMatch;
+    if (std::regex_search(command, jmxManagerPortMatch,
+                          jmxManagerPortRegex)) {
+      jmxManagerPort = jmxManagerPortMatch[1];
+    }
+
+    connection_ = "connect --jmx-manager=" + jmxManagerHost + "[" +
+        jmxManagerPort + "]";
+
+    if (!(user.empty() || password.empty())) {
+      connection_ += " --user=" + user + " --password=" + password;
+    }
+  }
+}
+
diff --git a/cppcache/integration/framework/GfshExecute.h b/cppcache/integration/framework/GfshExecute.h
index 39f95e9..b174828 100644
--- a/cppcache/integration/framework/GfshExecute.h
+++ b/cppcache/integration/framework/GfshExecute.h
@@ -34,7 +34,7 @@
                        w_constexprnonlitret, explctspectypename)
 
 #include "Gfsh.h"
-#include "config.h"
+#include "TestConfig.h"
 
 template <class _T>
 bool starts_with(const _T &input, const _T &match) {
@@ -70,38 +70,14 @@
   };
 
  protected:
-  void execute(const std::string &command) override;
+  void execute(const std::string &command, const std::string &user, const std::string &password) override;
 
   boost::process::child executeChild(std::vector<std::string> &commands,
                                      boost::process::environment &env,
                                      boost::process::ipstream &outStream,
                                      boost::process::ipstream &errStream);
 
-  void extractConnectionCommand(const std::string &command) {
-    if (starts_with(command, std::string("connect"))) {
-      connection_ = command;
-    } else if (starts_with(command, std::string("start locator"))) {
-      auto jmxManagerHost = std::string("localhost");
-      auto jmxManagerPort = std::string("1099");
-
-      std::regex jmxManagerHostRegex("bind-address=([^\\s]+)");
-      std::smatch jmxManagerHostMatch;
-      if (std::regex_search(command, jmxManagerHostMatch,
-                            jmxManagerHostRegex)) {
-        jmxManagerHost = jmxManagerHostMatch[1];
-      }
-
-      std::regex jmxManagerPortRegex("jmx-manager-port=(\\d+)");
-      std::smatch jmxManagerPortMatch;
-      if (std::regex_search(command, jmxManagerPortMatch,
-                            jmxManagerPortRegex)) {
-        jmxManagerPort = jmxManagerPortMatch[1];
-      }
-
-      connection_ = "connect --jmx-manager=" + jmxManagerHost + "[" +
-                    jmxManagerPort + "]";
-    }
-  }
+  void extractConnectionCommand(const std::string &command, const std::string &user = "", const std::string &password = "");
 
  private:
   std::string connection_;
diff --git a/cppcache/integration/framework/config.h.in b/cppcache/integration/framework/NamedType.h
similarity index 63%
copy from cppcache/integration/framework/config.h.in
copy to cppcache/integration/framework/NamedType.h
index 935175f..797aab7 100644
--- a/cppcache/integration/framework/config.h.in
+++ b/cppcache/integration/framework/NamedType.h
@@ -17,9 +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@"
+#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/config.h.in b/cppcache/integration/framework/TestConfig.cpp.in
similarity index 66%
copy from cppcache/integration/framework/config.h.in
copy to cppcache/integration/framework/TestConfig.cpp.in
index 935175f..2b35db3 100644
--- a/cppcache/integration/framework/config.h.in
+++ b/cppcache/integration/framework/TestConfig.cpp.in
@@ -15,11 +15,13 @@
  * limitations under the License.
  */
 
-#pragma once
+#include "framework/TestConfig.h"
 
-#ifndef INTEGRATION_TEST_FRAMEWORK_CONFIG_H
-#define INTEGRATION_TEST_FRAMEWORK_CONFIG_H
-
-#define GFSH_EXECUTABLE "@Geode_gfsh_EXECUTABLE@"
-
-#endif  // INTEGRATION_TEST_FRAMEWORK_CONFIG_H
+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/config.h.in b/cppcache/integration/framework/TestConfig.h
similarity index 82%
rename from cppcache/integration/framework/config.h.in
rename to cppcache/integration/framework/TestConfig.h
index 935175f..ac057b9 100644
--- a/cppcache/integration/framework/config.h.in
+++ b/cppcache/integration/framework/TestConfig.h
@@ -20,6 +20,8 @@
 #ifndef INTEGRATION_TEST_FRAMEWORK_CONFIG_H
 #define INTEGRATION_TEST_FRAMEWORK_CONFIG_H
 
-#define GFSH_EXECUTABLE "@Geode_gfsh_EXECUTABLE@"
+enum class FrameworkVariable {JavaObjectJarPath, GfShExecutable, TestCacheXmlDir};
 
-#endif  // INTEGRATION_TEST_FRAMEWORK_CONFIG_H
+const char *getFrameworkString(FrameworkVariable name);
+
+#endif // INTEGRATION_TEST_FRAMEWORK_CONFIG_H
diff --git a/cppcache/integration/test/AuthInitializeTest.cpp b/cppcache/integration/test/AuthInitializeTest.cpp
new file mode 100644
index 0000000..ff6dc36
--- /dev/null
+++ b/cppcache/integration/test/AuthInitializeTest.cpp
@@ -0,0 +1,214 @@
+/*
+ * 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 <chrono>
+#include <future>
+#include <iostream>
+#include <random>
+#include <thread>
+
+#include <gtest/gtest.h>
+
+#include <geode/AuthInitialize.hpp>
+#include <geode/Cache.hpp>
+#include <geode/CqAttributes.hpp>
+#include <geode/CqAttributesFactory.hpp>
+#include <geode/CqEvent.hpp>
+#include <geode/CqListener.hpp>
+#include <geode/PoolManager.hpp>
+#include <geode/QueryService.hpp>
+#include <geode/RegionFactory.hpp>
+#include <geode/RegionShortcut.hpp>
+
+#include "CacheRegionHelper.hpp"
+#include "SimpleAuthInitialize.hpp"
+#include "SimpleCqListener.hpp"
+#include "framework/Cluster.h"
+#include "framework/Framework.h"
+#include "framework/Gfsh.h"
+
+using apache::geode::client::AuthenticationFailedException;
+using apache::geode::client::AuthInitialize;
+using apache::geode::client::Cache;
+using apache::geode::client::Cacheable;
+using apache::geode::client::CacheableKey;
+using apache::geode::client::CacheableString;
+using apache::geode::client::CacheFactory;
+using apache::geode::client::CqAttributes;
+using apache::geode::client::CqAttributesFactory;
+using apache::geode::client::CqEvent;
+using apache::geode::client::CqListener;
+using apache::geode::client::CqOperation;
+using apache::geode::client::Exception;
+using apache::geode::client::HashMapOfCacheable;
+using apache::geode::client::NotConnectedException;
+using apache::geode::client::Pool;
+using apache::geode::client::Properties;
+using apache::geode::client::QueryService;
+using apache::geode::client::Region;
+using apache::geode::client::RegionShortcut;
+
+using std::chrono::minutes;
+
+const int32_t CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT = 100000;
+
+Cache createCache(std::shared_ptr<SimpleAuthInitialize> auth) {
+  auto cache = CacheFactory()
+                   .set("log-level", "debug")
+                   .set("log-file", "geode_native.log")
+                   .set("statistic-sampling-enabled", "false")
+                   .setAuthInitialize(auth)
+                   .create();
+
+  return cache;
+}
+
+std::shared_ptr<Pool> createPool(Cluster& cluster, Cache& cache,
+                                 bool subscriptionEnabled) {
+  auto poolFactory = cache.getPoolManager().createFactory();
+
+  cluster.applyLocators(poolFactory);
+  poolFactory.setPRSingleHopEnabled(true).setSubscriptionEnabled(
+      subscriptionEnabled);
+
+  return poolFactory.create("default");
+}
+
+std::shared_ptr<Region> setupRegion(Cache& cache,
+                                    const std::shared_ptr<Pool>& pool) {
+  auto region = cache.createRegionFactory(RegionShortcut::PROXY)
+                    .setPoolName(pool->getName())
+                    .create("region");
+
+  return region;
+}
+
+TEST(AuthInitializeTest, putGetWithBasicAuth) {
+  Cluster cluster(
+      Name(std::string(::testing::UnitTest::GetInstance()
+                           ->current_test_info()
+                           ->test_case_name()) +
+           "/" +
+           ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+      Classpath{getFrameworkString(FrameworkVariable::JavaObjectJarPath)},
+      SecurityManager{"javaobject.SimpleSecurityManager"}, User{"root"},
+      Password{"root-password"}, LocatorCount{1}, ServerCount{1});
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("PARTITION")
+      .execute();
+
+  auto authInitialize = std::make_shared<SimpleAuthInitialize>();
+  auto cache = createCache(authInitialize);
+  auto pool = createPool(cluster, cache, false);
+  auto region = setupRegion(cache, pool);
+
+  region->put("foo", "bar");
+  auto value = region->get("foo");
+  auto stringValue = std::dynamic_pointer_cast<CacheableString>(value)->value();
+  ASSERT_EQ(stringValue, std::string("bar"));
+  ASSERT_GT(authInitialize->getGetCredentialsCallCount(), 0);
+}
+
+TEST(AuthInitializeTest, putWithBadUsername) {
+  Cluster cluster(
+      Name(std::string(::testing::UnitTest::GetInstance()
+                           ->current_test_info()
+                           ->test_case_name()) +
+           "/" +
+           ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+      Classpath{getFrameworkString(FrameworkVariable::JavaObjectJarPath)},
+      SecurityManager{"javaobject.SimpleSecurityManager"}, User{"root"},
+      Password{"root-password"}, LocatorCount{1}, ServerCount{1});
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("PARTITION")
+      .execute();
+  auto authInitialize = std::make_shared<SimpleAuthInitialize>(
+      "unauthorized-user", "root-password");
+  auto cache = createCache(authInitialize);
+  auto pool = createPool(cluster, cache, false);
+  auto region = setupRegion(cache, pool);
+
+  try {
+    region->put("foo", "bar");
+  } catch (const NotConnectedException&) {
+  } catch (const Exception& ex) {
+    std::cerr << "Caught unexpected exception: " << ex.what() << std::endl;
+    FAIL();
+  }
+
+  ASSERT_GT(authInitialize->getGetCredentialsCallCount(), 0);
+}
+
+TEST(AuthInitializeTest, putWithBadPassword) {
+  Cluster cluster(
+      Name(std::string(::testing::UnitTest::GetInstance()
+                           ->current_test_info()
+                           ->test_case_name()) +
+           "/" +
+           ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+      Classpath{getFrameworkString(FrameworkVariable::JavaObjectJarPath)},
+      SecurityManager{"javaobject.SimpleSecurityManager"}, User{"root"},
+      Password{"root-password"}, LocatorCount{1}, ServerCount{1});
+
+  auto authInitialize =
+      std::make_shared<SimpleAuthInitialize>("root", "bad-password");
+  auto cache = createCache(authInitialize);
+  auto pool = createPool(cluster, cache, false);
+  auto region = setupRegion(cache, pool);
+
+  try {
+    region->put("foo", "bar");
+  } catch (const NotConnectedException&) {
+  } catch (const Exception& ex) {
+    std::cerr << "Caught unexpected exception: " << ex.what() << std::endl;
+    FAIL();
+  }
+
+  ASSERT_GT(authInitialize->getGetCredentialsCallCount(), 0);
+}
+
+TEST(AuthInitializeTest, badCredentialsWithSubscriptionEnabled) {
+  Cluster cluster(
+      Name(std::string(::testing::UnitTest::GetInstance()
+                           ->current_test_info()
+                           ->test_case_name()) +
+           "/" +
+           ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+      Classpath{getFrameworkString(FrameworkVariable::JavaObjectJarPath)},
+      SecurityManager{"javaobject.SimpleSecurityManager"}, User{"root"},
+      Password{"root-password"}, LocatorCount{1}, ServerCount{1});
+
+  auto authInitialize =
+      std::make_shared<SimpleAuthInitialize>("root", "bad-password");
+  auto cache = createCache(authInitialize);
+
+  try {
+    createPool(cluster, cache, true);
+  } catch (const AuthenticationFailedException&) {
+  } catch (const Exception& ex) {
+    std::cerr << "Caught unexpected exception: " << ex.what() << std::endl;
+    FAIL();
+  }
+
+  ASSERT_GT(authInitialize->getGetCredentialsCallCount(), 0);
+}
diff --git a/cppcache/integration/test/CMakeLists.txt b/cppcache/integration/test/CMakeLists.txt
index 76158ce..607fb08 100644
--- a/cppcache/integration/test/CMakeLists.txt
+++ b/cppcache/integration/test/CMakeLists.txt
@@ -14,20 +14,28 @@
 # limitations under the License.
 
 add_executable(cpp-integration-test
-  ChunkedHeaderTest.cpp
+  AuthInitializeTest.cpp
+  CacheXmlTest.cpp
+  CommitConflictExceptionTest.cpp
+  CqPlusAuthInitializeTest.cpp
+  CqTest.cpp
   DataSerializableTest.cpp
   EnableChunkHandlerThreadTest.cpp
   ExampleTest.cpp
   ExpirationTest.cpp
   FunctionExecutionTest.cpp
   PdxInstanceTest.cpp
+  RegionGetAllTest.cpp
   RegionPutAllTest.cpp
   RegionPutGetAllTest.cpp
   RegisterKeysTest.cpp
+  SimpleAuthInitialize.cpp
+  SimpleAuthInitialize.hpp
+  SimpleCqListener.cpp
+  SimpleCqListener.hpp
   StructTest.cpp
-  CommitConflictExceptionTest.cpp
   TransactionCleaningTest.cpp
-  )
+)
 
 target_compile_definitions(cpp-integration-test
   PUBLIC
@@ -72,6 +80,13 @@
   endforeach()
 endif()
 
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/func_cacheserver1_pool.xml
+  ${CMAKE_CURRENT_BINARY_DIR}/func_cacheserver1_pool.xml COPYONLY)
+configure_file(
+  ${CMAKE_CURRENT_SOURCE_DIR}/func_cacheserver2_pool.xml
+  ${CMAKE_CURRENT_BINARY_DIR}/func_cacheserver2_pool.xml COPYONLY)  
+
 set_target_properties(cpp-integration-test PROPERTIES
   CXX_VISIBILITY_PRESET hidden
   VISIBILITY_INLINES_HIDDEN ON
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/integration/test/ClientTransactionXATest.cpp b/cppcache/integration/test/ClientTransactionXATest.cpp
new file mode 100644
index 0000000..277013c
--- /dev/null
+++ b/cppcache/integration/test/ClientTransactionXATest.cpp
@@ -0,0 +1,91 @@
+/*
+ * 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 <gmock/gmock.h>
+
+#include <future>
+#include <thread>
+
+#include <gtest/gtest.h>
+
+#include <geode/Cache.hpp>
+#include <geode/CacheTransactionManager.hpp>
+#include <geode/RegionFactory.hpp>
+#include <geode/RegionShortcut.hpp>
+
+#include "framework/Cluster.h"
+
+namespace {
+
+using apache::geode::client::CacheableString;
+
+std::shared_ptr<apache::geode::client::Region> setupRegion(
+    apache::geode::client::Cache &cache) {
+  auto region =
+      cache.createRegionFactory(apache::geode::client::RegionShortcut::PROXY)
+          .setPoolName("default")
+          .create("region");
+  return region;
+}
+
+TEST(ClientTransactionXATest, interTxand2PCTx) {
+  Cluster cluster{LocatorCount{1}, ServerCount{1}};
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("PARTITION")
+      .execute();
+
+  auto cache = cluster.createCache();
+  auto region = setupRegion(cache);
+
+  cache.getCacheTransactionManager()->begin();
+  region->put("one", "one");
+  cache.getCacheTransactionManager()->commit();
+  auto v1 = std::dynamic_pointer_cast<CacheableString>(region->get("one"));
+  EXPECT_EQ("one", v1->value());
+
+  cache.getCacheTransactionManager()->begin();
+  region->put("two", "two");
+  cache.getCacheTransactionManager()->prepare();
+  cache.getCacheTransactionManager()->commit();
+  auto v2 = std::dynamic_pointer_cast<CacheableString>(region->get("two"));
+  EXPECT_EQ("two", v2->value());
+
+  cache.getCacheTransactionManager()->begin();
+  region->put("two", "three");
+  cache.getCacheTransactionManager()->prepare();
+  cache.getCacheTransactionManager()->rollback();
+  auto v3 = std::dynamic_pointer_cast<CacheableString>(region->get("two"));
+  EXPECT_EQ("two", v3->value());
+
+  cache.getCacheTransactionManager()->begin();
+  region->put("one", "three");
+  cache.getCacheTransactionManager()->rollback();
+  auto v4 = std::dynamic_pointer_cast<CacheableString>(region->get("one"));
+  EXPECT_EQ("one", v4->value());
+
+  cache.getCacheTransactionManager()->begin();
+  region->put("one", "two");
+  cache.getCacheTransactionManager()->prepare();
+  cache.getCacheTransactionManager()->commit();
+  auto v5 = std::dynamic_pointer_cast<CacheableString>(region->get("one"));
+  EXPECT_EQ("two", v5->value());
+}
+
+}  // namespace
diff --git a/cppcache/integration/test/CqPlusAuthInitializeTest.cpp b/cppcache/integration/test/CqPlusAuthInitializeTest.cpp
new file mode 100644
index 0000000..e591b3d
--- /dev/null
+++ b/cppcache/integration/test/CqPlusAuthInitializeTest.cpp
@@ -0,0 +1,206 @@
+/*
+ * 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 <chrono>
+#include <future>
+#include <iostream>
+#include <random>
+#include <thread>
+
+#include <gtest/gtest.h>
+
+#include <geode/AuthInitialize.hpp>
+#include <geode/Cache.hpp>
+#include <geode/CqAttributes.hpp>
+#include <geode/CqAttributesFactory.hpp>
+#include <geode/CqEvent.hpp>
+#include <geode/CqListener.hpp>
+#include <geode/PoolManager.hpp>
+#include <geode/QueryService.hpp>
+#include <geode/RegionFactory.hpp>
+#include <geode/RegionShortcut.hpp>
+
+#include "CacheRegionHelper.hpp"
+#include "SimpleAuthInitialize.hpp"
+#include "SimpleCqListener.hpp"
+#include "framework/Cluster.h"
+#include "framework/Framework.h"
+#include "framework/Gfsh.h"
+
+namespace {
+
+using apache::geode::client::AuthInitialize;
+using apache::geode::client::Cache;
+using apache::geode::client::Cacheable;
+using apache::geode::client::CacheableKey;
+using apache::geode::client::CacheableString;
+using apache::geode::client::CacheFactory;
+using apache::geode::client::CqAttributes;
+using apache::geode::client::CqAttributesFactory;
+using apache::geode::client::CqEvent;
+using apache::geode::client::CqListener;
+using apache::geode::client::CqOperation;
+using apache::geode::client::Exception;
+using apache::geode::client::HashMapOfCacheable;
+using apache::geode::client::Pool;
+using apache::geode::client::Properties;
+using apache::geode::client::QueryService;
+using apache::geode::client::Region;
+using apache::geode::client::RegionShortcut;
+
+using std::chrono::minutes;
+
+const int32_t CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT = 50000;
+
+Cache createCache(std::shared_ptr<SimpleAuthInitialize> auth) {
+  auto cache = CacheFactory()
+                   .set("log-level", "debug")
+                   .set("log-file", "geode_native.log")
+                   .set("statistic-sampling-enabled", "false")
+                   .setAuthInitialize(auth)
+                   .create();
+
+  return cache;
+}
+
+std::shared_ptr<Pool> createPool(Cluster& cluster, Cache& cache,
+                                 bool subscriptionEnabled) {
+  auto poolFactory = cache.getPoolManager().createFactory().setIdleTimeout(
+      std::chrono::milliseconds(0));
+
+  cluster.applyLocators(poolFactory);
+  poolFactory.setPRSingleHopEnabled(true).setSubscriptionEnabled(
+      subscriptionEnabled);
+
+  return poolFactory.create("default");
+}
+
+std::shared_ptr<Region> setupRegion(Cache& cache,
+                                    const std::shared_ptr<Pool>& pool) {
+  auto region = cache.createRegionFactory(RegionShortcut::PROXY)
+                    .setPoolName(pool->getName())
+                    .create("region");
+
+  return region;
+}
+
+TEST(CqPlusAuthInitializeTest, putInALoopWhileSubscribedAndAuthenticated) {
+  Cluster cluster(
+      Name(std::string(::testing::UnitTest::GetInstance()
+                           ->current_test_info()
+                           ->test_case_name()) +
+           "/" +
+           ::testing::UnitTest::GetInstance()->current_test_info()->name()),
+      Classpath{getFrameworkString(FrameworkVariable::JavaObjectJarPath)},
+      SecurityManager{"javaobject.SimpleSecurityManager"}, User{"root"},
+      Password{"root-password"}, LocatorCount{1}, ServerCount{1});
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("PARTITION")
+      .execute();
+
+  auto authInitialize = std::make_shared<SimpleAuthInitialize>();
+  auto cache = createCache(authInitialize);
+  auto pool = createPool(cluster, cache, true);
+  auto region = setupRegion(cache, pool);
+
+  try {
+    region->put("foo", "bar");
+  } catch (const Exception& ex) {
+    std::cerr << "Caught exception: " << ex.what() << std::endl;
+    std::cerr << "In initial region put" << std::endl;
+    std::cerr << "Callstack" << ex.getStackTrace() << std::endl;
+    FAIL();
+  }
+
+  auto queryService = cache.getQueryService();
+
+  CqAttributesFactory attributesFactory;
+  auto testListener = std::make_shared<SimpleCqListener>();
+  attributesFactory.addCqListener(testListener);
+  auto cqAttributes = attributesFactory.create();
+
+  auto query =
+      queryService->newCq("SimpleCQ", "SELECT * FROM /region", cqAttributes);
+
+  try {
+    query->execute();
+  } catch (const Exception& ex) {
+    std::cerr << "Caught exception: " << ex.what() << std::endl;
+    std::cerr << "While executing Cq" << std::endl;
+    std::cerr << "Callstack" << ex.getStackTrace() << std::endl;
+    FAIL();
+  }
+
+  int32_t i = 0;
+
+  try {
+    for (i = 0; i < CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT; i++) {
+      region->put("key" + std::to_string(i), "value" + std::to_string(i));
+      std::this_thread::yield();
+    }
+  } catch (const Exception& ex) {
+    std::cerr << "Caught exception: " << ex.what() << std::endl;
+    std::cerr << "In value create loop, i=" << i << std::endl;
+    std::cerr << "Callstack" << ex.getStackTrace() << std::endl;
+    FAIL();
+  }
+
+  try {
+    for (i = 0; i < CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT; i++) {
+      region->put("key" + std::to_string(i), "value" + std::to_string(i + 1));
+      std::this_thread::yield();
+    }
+  } catch (const Exception& ex) {
+    std::cerr << "Caught exception: " << ex.what() << std::endl;
+    std::cerr << "In value update loop, i=" << i << std::endl;
+    std::cerr << "Callstack" << ex.getStackTrace() << std::endl;
+    FAIL();
+  }
+
+  try {
+    for (i = 0; i < CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT; i++) {
+      region->destroy("key" + std::to_string(i));
+      std::this_thread::yield();
+    }
+  } catch (const Exception& ex) {
+    std::cerr << "Caught exception: " << ex.what() << std::endl;
+    std::cerr << "In value destroy loop, i=" << i << std::endl;
+    std::cerr << "Callstack" << ex.getStackTrace() << std::endl;
+    FAIL();
+  }
+
+  for (i = 0; i < 1000; i++) {
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    if (testListener->getDestructionCount() ==
+        CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT) {
+      break;
+    }
+  }
+
+  ASSERT_EQ(testListener->getCreationCount(),
+            CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT);
+  ASSERT_EQ(testListener->getUpdateCount(),
+            CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT);
+  ASSERT_EQ(testListener->getDestructionCount(),
+            CQ_PLUS_AUTH_TEST_REGION_ENTRY_COUNT);
+  ASSERT_GT(authInitialize->getGetCredentialsCallCount(), 0);
+}
+
+}  // namespace
diff --git a/cppcache/integration/test/CqTest.cpp b/cppcache/integration/test/CqTest.cpp
new file mode 100644
index 0000000..1d83b2e
--- /dev/null
+++ b/cppcache/integration/test/CqTest.cpp
@@ -0,0 +1,132 @@
+/*
+ * 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 <chrono>
+#include <future>
+#include <iostream>
+#include <random>
+#include <thread>
+
+#include <gtest/gtest.h>
+
+#include <geode/CqAttributesFactory.hpp>
+#include <geode/QueryService.hpp>
+#include <geode/RegionFactory.hpp>
+#include <geode/RegionShortcut.hpp>
+
+#include "CacheRegionHelper.hpp"
+#include "SimpleCqListener.hpp"
+#include "framework/Cluster.h"
+#include "framework/Framework.h"
+#include "framework/Gfsh.h"
+
+namespace {
+
+using apache::geode::client::Cache;
+using apache::geode::client::Cacheable;
+using apache::geode::client::CacheableKey;
+using apache::geode::client::CqAttributesFactory;
+using apache::geode::client::HashMapOfCacheable;
+using apache::geode::client::Pool;
+using apache::geode::client::Region;
+using apache::geode::client::RegionShortcut;
+
+using std::chrono::minutes;
+
+//
+// TODO: Use a random number of entries.  Need to investigate how to log this
+// from/import it to a test first.
+//
+const int32_t CQ_TEST_REGION_ENTRY_COUNT = 100;
+
+Cache createCache() {
+  using apache::geode::client::CacheFactory;
+
+  auto cache = CacheFactory()
+                   .set("log-level", "none")
+                   .set("statistic-sampling-enabled", "false")
+                   .create();
+
+  return cache;
+}
+
+std::shared_ptr<Pool> createPool(Cluster& cluster, Cache& cache) {
+  auto poolFactory = cache.getPoolManager().createFactory();
+  cluster.applyLocators(poolFactory);
+  poolFactory.setPRSingleHopEnabled(true);
+  poolFactory.setSubscriptionEnabled(true);
+  return poolFactory.create("default");
+}
+
+std::shared_ptr<Region> setupRegion(Cache& cache,
+                                    const std::shared_ptr<Pool>& pool) {
+  auto region = cache.createRegionFactory(RegionShortcut::PROXY)
+                    .setPoolName(pool->getName())
+                    .create("region");
+
+  return region;
+}
+
+TEST(CqTest, testCqCreateUpdateDestroy) {
+  Cluster cluster{LocatorCount{1}, ServerCount{2}};
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("PARTITION")
+      .execute();
+
+  auto cache = createCache();
+  auto pool = createPool(cluster, cache);
+  auto region = setupRegion(cache, pool);
+  auto queryService = cache.getQueryService();
+
+  CqAttributesFactory attributesFactory;
+  auto testListener = std::make_shared<SimpleCqListener>();
+  attributesFactory.addCqListener(testListener);
+  auto cqAttributes = attributesFactory.create();
+
+  auto query =
+      queryService->newCq("SimpleCQ", "SELECT * FROM /region", cqAttributes);
+
+  query->execute();
+
+  for (int i = 0; i < CQ_TEST_REGION_ENTRY_COUNT; i++) {
+    region->put("key" + std::to_string(i), "value" + std::to_string(i));
+  }
+
+  for (int i = 0; i < CQ_TEST_REGION_ENTRY_COUNT; i++) {
+    region->put("key" + std::to_string(i), "value" + std::to_string(i + 1));
+  }
+
+  for (int i = 0; i < CQ_TEST_REGION_ENTRY_COUNT; i++) {
+    region->destroy("key" + std::to_string(i));
+  }
+
+  for (int i = 0; i < 100; i++) {
+    std::this_thread::sleep_for(std::chrono::milliseconds(100));
+    if (testListener->getCreationCount() == CQ_TEST_REGION_ENTRY_COUNT) {
+      break;
+    }
+  }
+
+  ASSERT_EQ(testListener->getCreationCount(), CQ_TEST_REGION_ENTRY_COUNT);
+  ASSERT_EQ(testListener->getUpdateCount(), CQ_TEST_REGION_ENTRY_COUNT);
+  ASSERT_EQ(testListener->getDestructionCount(), CQ_TEST_REGION_ENTRY_COUNT);
+}
+
+}  // namespace
diff --git a/cppcache/integration/test/FunctionExecutionTest.cpp b/cppcache/integration/test/FunctionExecutionTest.cpp
index 06b9e02..d731c90 100644
--- a/cppcache/integration/test/FunctionExecutionTest.cpp
+++ b/cppcache/integration/test/FunctionExecutionTest.cpp
@@ -14,10 +14,11 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #include <gtest/gtest.h>
 
 #include <geode/Cache.hpp>
+#include <geode/CacheFactory.hpp>
+#include <geode/CacheableBuiltins.hpp>
 #include <geode/ExceptionTypes.hpp>
 #include <geode/FunctionService.hpp>
 #include <geode/PoolManager.hpp>
@@ -26,15 +27,21 @@
 
 #include "framework/Cluster.h"
 #include "framework/Gfsh.h"
+#include "framework/TestConfig.h"
 
 using apache::geode::client::Cache;
 using apache::geode::client::Cacheable;
+using apache::geode::client::CacheableArrayList;
+using apache::geode::client::CacheableString;
 using apache::geode::client::CacheableVector;
+using apache::geode::client::CacheFactory;
 using apache::geode::client::FunctionExecutionException;
 using apache::geode::client::FunctionService;
+using apache::geode::client::NotConnectedException;
 using apache::geode::client::Region;
 using apache::geode::client::RegionShortcut;
 using apache::geode::client::ResultCollector;
+const int ON_SERVERS_TEST_REGION_ENTRIES_SIZE = 34;
 
 std::shared_ptr<Region> setupRegion(Cache &cache) {
   auto region = cache.createRegionFactory(RegionShortcut::PROXY)
@@ -44,6 +51,19 @@
   return region;
 }
 
+class TestResultCollector : public ResultCollector {
+  virtual std::shared_ptr<CacheableVector> getResult(
+      std::chrono::milliseconds) override {
+    return std::shared_ptr<CacheableVector>();
+  }
+
+  virtual void addResult(const std::shared_ptr<Cacheable> &) override {}
+
+  virtual void endResults() override {}
+
+  virtual void clearResults() override {}
+};
+
 TEST(FunctionExecutionTest, UnknownFunctionOnServer) {
   Cluster cluster{LocatorCount{1}, ServerCount{1}};
   cluster.getGfsh()
@@ -77,19 +97,6 @@
                FunctionExecutionException);
 }
 
-class TestResultCollector : public ResultCollector {
-  virtual std::shared_ptr<CacheableVector> getResult(
-      std::chrono::milliseconds) override {
-    return std::shared_ptr<CacheableVector>();
-  }
-
-  virtual void addResult(const std::shared_ptr<Cacheable> &) override {}
-
-  virtual void endResults() override {}
-
-  virtual void clearResults() override {}
-};
-
 TEST(FunctionExecutionTest, UnknownFunctionAsyncOnServer) {
   Cluster cluster{LocatorCount{1}, ServerCount{1}};
   cluster.getGfsh()
@@ -125,3 +132,109 @@
                    .execute("I_Don_t_Exist"),
                FunctionExecutionException);
 }
+
+TEST(FunctionExecutionTest,
+     Disabled_FunctionReturnsObjectWhichCantBeDeserializedOnServer) {
+  Cluster cluster{LocatorCount{1}, ServerCount{1}};
+  cluster.getGfsh()
+      .create()
+      .region()
+      .withName("region")
+      .withType("REPLICATE")
+      .execute();
+
+  cluster.getGfsh()
+      .deploy()
+      .jar(getFrameworkString(FrameworkVariable::JavaObjectJarPath))
+      .execute();
+
+  auto cache = cluster.createCache();
+  auto region = cache.createRegionFactory(RegionShortcut::PROXY)
+                    .setPoolName("default")
+                    .create("region");
+
+  const char *GetScopeSnapshotsFunction =
+      "executeFunction_SendObjectWhichCantBeDeserialized";
+  auto functionService = FunctionService::onRegion(region);
+  ASSERT_THROW(functionService.execute(GetScopeSnapshotsFunction),
+               apache::geode::client::IllegalStateException);
+
+  cache.close();
+}
+
+const std::vector<std::string> serverResultsToStrings(
+    std::shared_ptr<CacheableVector> serverResults) {
+  std::vector<std::string> resultList;
+  for (auto result : *serverResults) {
+    auto resultArray = std::dynamic_pointer_cast<CacheableArrayList>(result);
+    for (decltype(resultArray->size()) i = 0; i < resultArray->size(); i++) {
+      auto value =
+          std::dynamic_pointer_cast<CacheableString>(resultArray->at(i));
+      resultList.push_back(value->toString());
+    }
+  }
+
+  return resultList;
+}
+TEST(FunctionExecutionTest, OnServersWithReplicatedRegionsInPool) {
+  Cluster cluster{
+      LocatorCount{1}, ServerCount{2},
+      CacheXMLFiles(
+          {std::string(getFrameworkString(FrameworkVariable::TestCacheXmlDir)) +
+               "/func_cacheserver1_pool.xml",
+           std::string(getFrameworkString(FrameworkVariable::TestCacheXmlDir)) +
+               "/func_cacheserver2_pool.xml"})};
+
+  cluster.start([&]() {
+    cluster.getGfsh()
+        .deploy()
+        .jar(getFrameworkString(FrameworkVariable::JavaObjectJarPath))
+        .execute();
+  });
+
+  auto cache = CacheFactory().set("log-level", "none").create();
+  auto poolFactory = cache.getPoolManager().createFactory();
+
+  cluster.applyLocators(poolFactory);
+
+  auto pool = poolFactory.create("pool");
+
+  auto region = cache.createRegionFactory(RegionShortcut::PROXY)
+                    .setPoolName("pool")
+                    .create("partition_region");
+
+  for (int i = 0; i < ON_SERVERS_TEST_REGION_ENTRIES_SIZE; i++) {
+    region->put("KEY--" + std::to_string(i), "VALUE--" + std::to_string(i));
+  }
+
+  // Filter on odd keys
+  auto routingObj = CacheableVector::create();
+  for (int i = 0; i < ON_SERVERS_TEST_REGION_ENTRIES_SIZE; i++) {
+    if (i % 2 == 0) {
+      continue;
+    }
+    routingObj->push_back(CacheableString::create("KEY--" + std::to_string(i)));
+  }
+
+  auto execution = FunctionService::onServers(pool);
+
+  auto rc = execution.withArgs(routingObj).execute("MultiGetFunctionI");
+  auto executeFunctionResult = rc->getResult();
+
+  // Executed on 2 servers, we should have two sets of results
+  ASSERT_EQ(executeFunctionResult->size(), 2);
+
+  auto resultList = serverResultsToStrings(executeFunctionResult);
+
+  // We filtered on odd keys, we should have 1/2 as many results in each set,
+  // for a total of ON_SERVERS_TEST_REGION_ENTRIES_SIZE results
+  ASSERT_EQ(resultList.size(), ON_SERVERS_TEST_REGION_ENTRIES_SIZE);
+
+  for (decltype(resultList.size()) i = 0;
+       i < ON_SERVERS_TEST_REGION_ENTRIES_SIZE / 2; i++) {
+    // Each entry in the first result set (first half of this vector) should be
+    // equal to its corresponding entry in the second set (2nd half of vector)
+    ASSERT_EQ(resultList[i],
+              resultList[i + ON_SERVERS_TEST_REGION_ENTRIES_SIZE / 2]);
+  }
+}
diff --git a/cppcache/integration/test/SimpleAuthInitialize.cpp b/cppcache/integration/test/SimpleAuthInitialize.cpp
new file mode 100644
index 0000000..945279a
--- /dev/null
+++ b/cppcache/integration/test/SimpleAuthInitialize.cpp
@@ -0,0 +1,63 @@
+/*
+ * 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 "SimpleAuthInitialize.hpp"
+
+#include <chrono>
+#include <future>
+#include <iostream>
+#include <random>
+#include <thread>
+
+#include <gtest/gtest.h>
+
+using apache::geode::client::AuthInitialize;
+using apache::geode::client::Properties;
+
+std::shared_ptr<Properties> SimpleAuthInitialize::getCredentials(
+    const std::shared_ptr<Properties>& securityprops,
+    const std::string& /*server*/) {
+  std::cout << "SimpleAuthInitialize::GetCredentials called\n";
+
+  securityprops->insert("security-username", username_);
+  securityprops->insert("security-password", password_);
+
+  countOfGetCredentialsCalls_++;
+  return securityprops;
+}
+
+void SimpleAuthInitialize::close() {
+  std::cout << "SimpleAuthInitialize::close called\n";
+}
+
+SimpleAuthInitialize::SimpleAuthInitialize()
+    : AuthInitialize(),
+      username_("root"),
+      password_("root-password"),
+      countOfGetCredentialsCalls_(0) {
+  std::cout << "SimpleAuthInitialize::SimpleAuthInitialize called\n";
+}
+
+SimpleAuthInitialize::SimpleAuthInitialize(std::string username,
+                                           std::string password)
+    : username_(std::move(username)),
+      password_(std::move(password)),
+      countOfGetCredentialsCalls_(0) {}
+
+int32_t SimpleAuthInitialize::getGetCredentialsCallCount() {
+  return countOfGetCredentialsCalls_;
+}
diff --git a/cppcache/integration/test/SimpleAuthInitialize.hpp b/cppcache/integration/test/SimpleAuthInitialize.hpp
new file mode 100644
index 0000000..cd72177
--- /dev/null
+++ b/cppcache/integration/test/SimpleAuthInitialize.hpp
@@ -0,0 +1,50 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef SIMPLEAUTHINITIALIZE_H_
+#define SIMPLEAUTHINITIALIZE_H_
+
+#include <string>
+
+#include <geode/AuthInitialize.hpp>
+#include <geode/Properties.hpp>
+
+class SimpleAuthInitialize : public apache::geode::client::AuthInitialize {
+ public:
+  std::shared_ptr<apache::geode::client::Properties> getCredentials(
+      const std::shared_ptr<apache::geode::client::Properties>& securityprops,
+      const std::string& /*server*/) override;
+
+  void close() override;
+
+  SimpleAuthInitialize();
+
+  SimpleAuthInitialize(std::string username, std::string password);
+
+  ~SimpleAuthInitialize() override = default;
+
+  int32_t getGetCredentialsCallCount();
+
+ private:
+  std::string username_;
+  std::string password_;
+  int32_t countOfGetCredentialsCalls_;
+};
+
+#endif  // SIMPLEAUTHINITIALIZE_H_
diff --git a/cppcache/integration/test/SimpleCqListener.cpp b/cppcache/integration/test/SimpleCqListener.cpp
new file mode 100644
index 0000000..77e9778
--- /dev/null
+++ b/cppcache/integration/test/SimpleCqListener.cpp
@@ -0,0 +1,60 @@
+/*
+ * 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 "SimpleCqListener.hpp"
+
+#include <iostream>
+
+#include <geode/CqListener.hpp>
+#include <geode/CqOperation.hpp>
+
+SimpleCqListener::SimpleCqListener()
+    : creationCount_(0), updateCount_(0), destructionCount_(0) {}
+
+void SimpleCqListener::onEvent(const apache::geode::client::CqEvent& cqEvent) {
+  switch (cqEvent.getQueryOperation()) {
+    case apache::geode::client::CqOperation::OP_TYPE_CREATE:
+      creationCount_++;
+      break;
+    case apache::geode::client::CqOperation::OP_TYPE_UPDATE:
+      updateCount_++;
+      break;
+    case apache::geode::client::CqOperation::OP_TYPE_DESTROY:
+      destructionCount_++;
+      break;
+    default:
+      break;
+  }
+}
+
+void SimpleCqListener::onError(const apache::geode::client::CqEvent& cqEvent) {
+  std::cout << __FUNCTION__ << " called"
+            << dynamic_cast<apache::geode::client::CacheableString*>(
+                   cqEvent.getKey().get())
+                   ->value()
+            << std::endl;
+}
+
+void SimpleCqListener::close() {
+  std::cout << __FUNCTION__ << " called" << std::endl;
+}
+
+int32_t SimpleCqListener::getCreationCount() { return creationCount_; }
+
+int32_t SimpleCqListener::getUpdateCount() { return updateCount_; }
+
+int32_t SimpleCqListener::getDestructionCount() { return destructionCount_; }
diff --git a/cppcache/integration/test/SimpleCqListener.hpp b/cppcache/integration/test/SimpleCqListener.hpp
new file mode 100644
index 0000000..e42d381
--- /dev/null
+++ b/cppcache/integration/test/SimpleCqListener.hpp
@@ -0,0 +1,44 @@
+/*
+ * 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.
+ */
+
+#pragma once
+
+#ifndef SIMPLE_CQ_LISTENER_H
+#define SIMPLE_CQ_LISTENER_H
+
+#include <geode/CacheableString.hpp>
+#include <geode/CqListener.hpp>
+#include <geode/CqOperation.hpp>
+
+class SimpleCqListener : public apache::geode::client::CqListener {
+ public:
+  SimpleCqListener();
+  void onEvent(const apache::geode::client::CqEvent& cqEvent) override;
+  void onError(const apache::geode::client::CqEvent& cqEvent) override;
+  void close() override;
+
+  int32_t getCreationCount();
+  int32_t getUpdateCount();
+  int32_t getDestructionCount();
+
+ private:
+  int32_t creationCount_;
+  int32_t updateCount_;
+  int32_t destructionCount_;
+};
+
+#endif  // SIMPLE_CQ_LISTENER_H
diff --git a/cppcache/integration/test/func_cacheserver1_pool.xml b/cppcache/integration/test/func_cacheserver1_pool.xml
new file mode 100644
index 0000000..820faa5
--- /dev/null
+++ b/cppcache/integration/test/func_cacheserver1_pool.xml
@@ -0,0 +1,86 @@
+<?xml version="1.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.
+-->
+<cache 
+	xmlns="http://geode.apache.org/schema/cache" 
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
+	<!--cache-server host="cod" port="24680" /-->
+	<cache-server port="HOST_PORT1">
+		<group>ServerGroup1</group>
+	</cache-server>
+	<pdx read-serialized="true" />
+	<region name='partition_region'>
+		<region-attributes data-policy="partition">
+			<partition-attributes redundant-copies="1" startup-recovery-delay="1"/>
+		</region-attributes>
+	</region>
+	<function-service>
+		<function>
+			<class-name>javaobject.MultiGetFunctionI</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiPutFunctionI</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiGetFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiGetFunction2</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiPutFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.RegionOperationsFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.RegionOperationsHAFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.ExceptionHandlingFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.OnServerHAExceptionFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.OnServerHAShutdownFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.PdxFunctionTest</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.SingleStrGetFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.executeFunction_SendException</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.FEOnRegionPrSHOP</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.FEOnRegionPrSHOP_OptimizeForWrite</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.RegionOperationsHAFunctionPrSHOP</class-name>
+		</function>
+	</function-service>
+	<serialization-registration>
+		<instantiator id="5200">
+			<class-name>javaobject.InstantiatorTest</class-name>
+		</instantiator>
+	</serialization-registration>
+</cache>
\ No newline at end of file
diff --git a/cppcache/integration/test/func_cacheserver2_pool.xml b/cppcache/integration/test/func_cacheserver2_pool.xml
new file mode 100644
index 0000000..354b1ff
--- /dev/null
+++ b/cppcache/integration/test/func_cacheserver2_pool.xml
@@ -0,0 +1,85 @@
+<?xml version="1.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.
+-->
+<cache 
+	xmlns="http://geode.apache.org/schema/cache" 
+	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://geode.apache.org/schema/cache http://geode.apache.org/schema/cache/cache-1.0.xsd" version="1.0">
+	<cache-server port="HOST_PORT2">
+		<group>ServerGroup1</group>
+	</cache-server>
+	<pdx read-serialized="true" />
+	<region name='partition_region'>
+		<region-attributes data-policy="partition">
+			<partition-attributes redundant-copies="1" startup-recovery-delay="1"/>
+		</region-attributes>
+	</region>
+	<function-service>
+		<function>
+			<class-name>javaobject.MultiGetFunctionI</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiPutFunctionI</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiGetFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiGetFunction2</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.MultiPutFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.RegionOperationsHAFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.RegionOperationsFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.ExceptionHandlingFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.OnServerHAExceptionFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.OnServerHAShutdownFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.SingleStrGetFunction</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.executeFunction_SendException</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.RegionOperationsHAFunctionPrSHOP</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.PdxFunctionTest</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.FEOnRegionPrSHOP</class-name>
+		</function>
+		<function>
+			<class-name>javaobject.FEOnRegionPrSHOP_OptimizeForWrite</class-name>
+		</function>
+	</function-service>
+	<serialization-registration>
+		<instantiator id="5200">
+			<class-name>javaobject.InstantiatorTest</class-name>
+		</instantiator>
+	</serialization-registration>
+</cache>
\ No newline at end of file
diff --git a/cppcache/src/AdminRegion.cpp b/cppcache/src/AdminRegion.cpp
index e08c734..ccc6139 100644
--- a/cppcache/src/AdminRegion.cpp
+++ b/cppcache/src/AdminRegion.cpp
@@ -70,7 +70,7 @@
 void AdminRegion::put(const std::shared_ptr<CacheableKey>& keyPtr,
                       const std::shared_ptr<Cacheable>& valuePtr) {
   GfErrType err = putNoThrow(keyPtr, valuePtr);
-  GfErrTypeToException("AdminRegion::put", err);
+  throwExceptionIfError("AdminRegion::put", err);
 }
 
 GfErrType AdminRegion::putNoThrow(const std::shared_ptr<CacheableKey>& keyPtr,
diff --git a/cppcache/src/Assert.cpp b/cppcache/src/Assert.cpp
deleted file mode 100644
index eee59ac..0000000
--- a/cppcache/src/Assert.cpp
+++ /dev/null
@@ -1,43 +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 "Assert.hpp"
-
-#include <sstream>
-
-#include <boost/stacktrace.hpp>
-
-#include <geode/ExceptionTypes.hpp>
-
-#include "util/Log.hpp"
-
-namespace apache {
-namespace geode {
-namespace client {
-
-void Assert::throwAssertion(const char* expressionText, const char* file,
-                            int line) {
-  AssertionException ae(expressionText);
-  LOGERROR("AssertionException: ( %s ) at %s:%d", expressionText, file, line);
-  std::stringstream ss;
-  ss << boost::stacktrace::stacktrace();
-  LOGERROR(ss.str().c_str());
-  throw ae;
-}
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
diff --git a/cppcache/src/Assert.hpp b/cppcache/src/Assert.hpp
deleted file mode 100644
index 7350fbc..0000000
--- a/cppcache/src/Assert.hpp
+++ /dev/null
@@ -1,100 +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.
- */
-
-#pragma once
-
-#ifndef GEODE_ASSERT_H_
-#define GEODE_ASSERT_H_
-
-#include <geode/internal/geode_globals.hpp>
-
-/**
- * @file
- *
- *  Assertion functions for debugging
- */
-
-namespace apache {
-namespace geode {
-namespace client {
-
-/**
- * @class Assert Assert.hpp
- *
- * Declares debugging assertion reporting functions.
- */
-class APACHE_GEODE_EXPORT Assert {
- public:
-  /** If the given expression is true, does nothing, otherwise calls
-   * @ref throwAssertion .
-   */
-  inline static void assertTrue(bool expression, const char* expressionText,
-                                const char* file, int line) {
-    if (!expression) {
-      throwAssertion(expressionText, file, line);
-    }
-  }
-
-  /** Throws the given assertion.
-   */
-  [[noreturn]] static void throwAssertion(const char* expressionText,
-                                          const char* file, int line);
-};
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
-
-/** Throws the given assertion. */
-#define GF_R_ASSERT(x) \
-  apache::geode::client::Assert::assertTrue(x, #x, __FILE__, __LINE__)
-
-#ifndef GF_DEBUG_ASSERTS
-/** Change this to 1 to use assertion functions. */
-#define GF_DEBUG_ASSERTS 0
-#endif
-
-#ifndef GF_DEVEL_ASSERTS
-#define GF_DEVEL_ASSERTS 0
-#endif
-
-#if GF_DEVEL_ASSERTS == 1
-#undef GF_DEBUG_ASSERTS
-#define GF_DEBUG_ASSERTS 1
-#endif
-
-#if GF_DEBUG_ASSERTS == 1
-#undef GF_DEVEL_ASSERTS
-#define GF_DEVEL_ASSERTS 1
-#endif
-
-/** Throws the given assertion if GF_DEBUG_ASSERTS is true. */
-#if GF_DEBUG_ASSERTS == 1
-#define GF_D_ASSERT(x) \
-  apache::geode::client::Assert::assertTrue(x, #x, __FILE__, __LINE__)
-#else
-#define GF_D_ASSERT(x)
-#endif
-
-/** Throws the given assertion if GF_DEVEL_ASSERTS is true. */
-#if GF_DEVEL_ASSERTS == 1
-#define GF_DEV_ASSERT(x) \
-  apache::geode::client::Assert::assertTrue(x, #x, __FILE__, __LINE__)
-#else
-#define GF_DEV_ASSERT(x)
-#endif
-
-#endif  // GEODE_ASSERT_H_
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/CacheImpl.cpp b/cppcache/src/CacheImpl.cpp
index 4ba2b12..7853fdc 100644
--- a/cppcache/src/CacheImpl.cpp
+++ b/cppcache/src/CacheImpl.cpp
@@ -79,7 +79,7 @@
       m_authInitialize(authInitialize) {
   using apache::geode::statistics::StatisticsManager;
 
-  m_cacheTXManager = std::shared_ptr<InternalCacheTransactionManager2PC>(
+  m_cacheTXManager = std::shared_ptr<CacheTransactionManager>(
       new InternalCacheTransactionManager2PCImpl(this));
 
   auto& prop = m_distributedSystem.getSystemProperties();
diff --git a/cppcache/src/CachePerfStats.hpp b/cppcache/src/CachePerfStats.hpp
index aac896b..9c7ad7e 100644
--- a/cppcache/src/CachePerfStats.hpp
+++ b/cppcache/src/CachePerfStats.hpp
@@ -22,7 +22,6 @@
 
 #include <geode/internal/geode_globals.hpp>
 
-#include "Assert.hpp"
 #include "statistics/Statistics.hpp"
 #include "statistics/StatisticsFactory.hpp"
 #include "statistics/StatisticsManager.hpp"
@@ -142,7 +141,6 @@
                                       "Statistics about native client cache",
                                       statDescArr, 24);
     }
-    GF_D_ASSERT(statsType != nullptr);
     // Create Statistics object
     m_cachePerfStats =
         factory->createAtomicStatistics(statsType, "CachePerfStats");
diff --git a/cppcache/src/CacheTransactionManagerImpl.cpp b/cppcache/src/CacheTransactionManagerImpl.cpp
index 8462736..d4a5a83 100644
--- a/cppcache/src/CacheTransactionManagerImpl.cpp
+++ b/cppcache/src/CacheTransactionManagerImpl.cpp
@@ -125,7 +125,7 @@
   try {
     GfErrType err = rollback(txState, true);
     if (err != GF_NOERR) {
-      GfErrTypeToException("Error while committing", err);
+      throwExceptionIfError("Error while committing", err);
     }
   } catch (const Exception& ex) {
     // TODO: put a log message
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..ac9892d 100644
--- a/cppcache/src/CacheXmlParser.cpp
+++ b/cppcache/src/CacheXmlParser.cpp
@@ -38,16 +38,171 @@
 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";
 
-using apache::geode::client::impl::getFactoryFunc;
+/** 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";
+
+/** 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 @@
 }
 }  // 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 @@
  * 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,196 @@
           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 */
-  };
+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));
 
-  m_saxHandler = saxHandler;
-
-  namedRegions = CacheImpl::getRegionShortcut();
+  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);
-
-  if (res == -1) {
-    throw CacheXmlException("Xml file " + std::string(filename) + " not found");
+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);
   }
-  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);
-
-  if (res == -1) {
-    throw CacheXmlException("Unable to read buffer.");
+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::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));
+void CacheXmlParser::fatalError(const xercesc::SAXParseException &exception) {
+  char *message = xercesc::XMLString::transcode(exception.getMessage());
+  LOGDEBUG("Fatal Error: \"%s\" at line: %ulld", message,
+           exception.getLineNumber());
+  auto ex = CacheXmlException(message);
+  xercesc::XMLString::release(&message);
+  throw ex;
+}
+
+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);
   }
-  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("");
+
+  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::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 +459,8 @@
  *         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 +472,7 @@
   }
 }
 
-void CacheXmlParser::setAttributes(Cache*) {}
+void CacheXmlParser::setAttributes(Cache *) {}
 
 /**
  * Creates cache artifacts ({@link Cache}s, etc.) based upon the XML
@@ -420,203 +491,259 @@
  * @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());
+
+  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);
+  }
+
+  return {translatedValue.get()};
 }
 
-void CacheXmlParser::startPdx(const xmlChar** atts) {
-  if (!atts) {
-    return;
+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); };
+
+  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));
   }
 
-  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 (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>");
+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);
       }
-      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);
+    }
+  }
+
+  value = getOptionalAttribute(attrs, REDUNDANCY_LEVEL);
+  if (!value.empty()) {
+    if (poolFactory_) {
+      poolFactory_->setSubscriptionRedundancy(std::stoi(value));
+    }
+  }
+
+  _GEODE_NEW(cacheCreation_, CacheXmlCreation());
+}
+
+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 pdx attribute " + name);
+      cacheCreation_->setPdxIgnoreUnreadField(false);
     }
   }
-}
 
-void CacheXmlParser::endPdx() {}
-
-void CacheXmlParser::startLocator(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <locator>. A locator requires a host "
-        "and port");
-  }
-  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);
-    }
-
-    if (HOST == name) {
-      host = std::move(value);
-    } else if (PORT == name) {
-      port = std::move(value);
+  auto pdxReadSerialized = getOptionalAttribute(attrs, READ_SERIALIZED);
+  if (!pdxReadSerialized.empty()) {
+    if (equal_ignore_case(pdxReadSerialized, "true")) {
+      cacheCreation_->setPdxReadSerialized(true);
     } else {
-      throw CacheXmlException("XML:Unrecognized locator attribute");
+      cacheCreation_->setPdxReadSerialized(false);
     }
-
-    ++attrsCount;
   }
-
-  if (attrsCount < 2) {
-    throw CacheXmlException(
-        "XML:Not enough attributes provided for a <locator> - host and port "
-        "required");
-  }
-
-  m_poolFactory->addLocator(host, std::stoi(port));
 }
 
-void CacheXmlParser::startServer(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException(
-        "XML:No attributes provided for <server>. A server requires a host and "
-        "port");
-  }
+void CacheXmlParser::startLocator(const xercesc::Attributes &attrs) {
+  poolFactory_ = std::static_pointer_cast<PoolFactory>(_stack.top());
+
+  auto host = getRequiredAttribute(attrs, HOST);
+  auto port = getRequiredAttribute(attrs, PORT);
+
+  poolFactory_->addLocator(host, std::stoi(port));
+}
+
+void CacheXmlParser::startServer(const xercesc::Attributes &attrs) {
   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);
-    } else {
-      throw CacheXmlException("XML:Unrecognized server attribute");
-    }
-
-    ++attrsCount;
-  }
-
-  if (attrsCount < 2) {
-    throw CacheXmlException(
-        "XML:Not enough attributes provided for a <server> - host and port "
-        "required");
-  }
+  auto host = getRequiredAttribute(attrs, HOST);
+  auto port = getRequiredAttribute(attrs, PORT);
 
   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");
-  }
+void CacheXmlParser::startPool(const xercesc::Attributes &attrs) {
+  using apache::geode::client::equal_ignore_case;
+  using apache::geode::internal::chrono::duration::from_string;
+
   auto factory =
-      std::make_shared<PoolFactory>(m_cache->getPoolManager().createFactory());
+      std::make_shared<PoolFactory>(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);
-    } else {
-      setPoolInfo(factory.get(), name.c_str(), value.c_str());
-    }
-  }
-
-  if (poolName.empty()) {
-    throw CacheXmlException(
-        "XML:No attributes provided for a <pool> - at least the name is "
-        "required");
-  }
+  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>(freeConnectionTimeout));
+  }
+
+  auto multiUserSecureMode = getOptionalAttribute(attrs, MULTIUSER_SECURE_MODE);
+  if (!multiUserSecureMode.empty()) {
+    if (equal_ignore_case(multiUserSecureMode, "true")) {
+      factory->setMultiuserAuthentication(true);
+    } else {
+      factory->setMultiuserAuthentication(false);
+    }
+  }
+
+  auto idleTimeout = getOptionalAttribute(attrs, IDLE_TIMEOUT);
+  if (!idleTimeout.empty()) {
+    factory->setIdleTimeout(
+        from_string<std::chrono::milliseconds>(idleTimeout));
+  }
+
+  auto loadConditioningInterval =
+      getOptionalAttribute(attrs, LOAD_CONDITIONING_INTERVAL);
+  if (!loadConditioningInterval.empty()) {
+    factory->setLoadConditioningInterval(
+        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(pingInterval)));
+  }
+
+  auto updateLocatorListInterval =
+      getOptionalAttribute(attrs, UPDATE_LOCATOR_LIST_INTERVAL);
+  if (!updateLocatorListInterval.empty()) {
+    factory->setUpdateLocatorListInterval(
+        from_string<std::chrono::milliseconds>(updateLocatorListInterval));
+  }
+
+  auto readTimeout = getOptionalAttribute(attrs, READ_TIMEOUT);
+  if (!readTimeout.empty()) {
+    factory->setReadTimeout(
+        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>(statisticInterval));
+  }
+
+  auto subscriptionAckInterval =
+      getOptionalAttribute(attrs, SUBSCRIPTION_ACK_INTERVAL);
+  if (!subscriptionAckInterval.empty()) {
+    factory->setSubscriptionAckInterval(
+        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);
+    }
+  }
+
+  auto subscriptionMessageTrackingTimeout =
+      getOptionalAttribute(attrs, SUBSCRIPTION_MTT);
+  if (!subscriptionMessageTrackingTimeout.empty()) {
+    factory->setSubscriptionMessageTrackingTimeout(
+        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);
+    }
+  }
+
+  auto prSingleHopEnabled = getOptionalAttribute(attrs, PR_SINGLE_HOP_ENABLED);
+  if (!prSingleHopEnabled.empty()) {
+    if (equal_ignore_case(prSingleHopEnabled, "true")) {
+      factory->setPRSingleHopEnabled(true);
+    } else {
+      factory->setPRSingleHopEnabled(false);
+    }
+  }
+
   _stack.push(poolxml);
   _stack.push(factory);
 }
@@ -625,81 +752,7 @@
   _stack.pop();  // remove factory
   auto poolxml = std::static_pointer_cast<PoolXmlCreation>(_stack.top());
   _stack.pop();  // remove pool
-  m_cacheCreation->addPool(poolxml);
-}
-
-void CacheXmlParser::setPoolInfo(PoolFactory* factory, const char* name,
-                                 const char* value) {
-  using apache::geode::client::equal_ignore_case;
-  using apache::geode::internal::chrono::duration::from_string;
-
-  if (strcmp(name, FREE_CONNECTION_TIMEOUT) == 0) {
-    factory->setFreeConnectionTimeout(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, MULTIUSER_SECURE_MODE) == 0) {
-    if (equal_ignore_case(value, "true")) {
-      factory->setMultiuserAuthentication(true);
-    } else {
-      factory->setMultiuserAuthentication(false);
-    }
-  } else if (strcmp(name, IDLE_TIMEOUT) == 0) {
-    factory->setIdleTimeout(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, LOAD_CONDITIONING_INTERVAL) == 0) {
-    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) {
-    factory->setPingInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, UPDATE_LOCATOR_LIST_INTERVAL) == 0) {
-    factory->setUpdateLocatorListInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, READ_TIMEOUT) == 0) {
-    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) {
-    factory->setStatisticInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, SUBSCRIPTION_ACK_INTERVAL) == 0) {
-    factory->setSubscriptionAckInterval(
-        from_string<std::chrono::milliseconds>(std::string(value)));
-  } else if (strcmp(name, SUBSCRIPTION_ENABLED) == 0) {
-    if (equal_ignore_case(value, "true")) {
-      factory->setSubscriptionEnabled(true);
-    } else {
-      factory->setSubscriptionEnabled(false);
-    }
-  } else if (strcmp(name, SUBSCRIPTION_MTT) == 0) {
-    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")) {
-      factory->setThreadLocalConnections(true);
-    } else {
-      factory->setThreadLocalConnections(false);
-    }
-  } else if (strcmp(name, PR_SINGLE_HOP_ENABLED) == 0) {
-    if (equal_ignore_case(value, "true")) {
-      factory->setPRSingleHopEnabled(true);
-    } else {
-      factory->setPRSingleHopEnabled(false);
-    }
-  } else {
-    throw CacheXmlException("XML:Unrecognized pool attribute " +
-                            std::string(name));
-  }
+  cacheCreation_->addPool(poolxml);
 }
 
 /**
@@ -707,113 +760,61 @@
  * 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");
+
+  if (attrs.getLength() > 24) {
+    throw CacheXmlException(
+        "XML:Too many attributes provided for <region-attributes>");
+  }
+
+  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);
     }
 
-    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 (ID == name) {
-        auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
-        region->setAttrId(value);
-      } else if (REFID == name) {
-        refid = std::move(value);
-      }
-    }
-
+    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 +823,147 @@
 
     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>");
-        }
-        regionAttributesFactory->setConcurrencyChecksEnabled(flag);
+    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>");
       }
-    }  // 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);
+      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);
+        }
+      }
+      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 +984,7 @@
 
   std::string id = regionPtr->getAttrId();
   if (id != "") {
-    namedRegions[id] = regionAttributes;
+    namedRegions_[id] = regionAttributes;
   }
 
   regionPtr->setAttributes(regionAttributes);
@@ -966,64 +995,45 @@
  * 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 +1046,69 @@
 
   _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]));
+void CacheXmlParser::startPersistenceProperty(
+    const xercesc::Attributes &attrs) {
+  auto propertyName = getRequiredAttribute(attrs, NAME);
+  auto propertyValue = getRequiredAttribute(attrs, VALUE);
 
-    if (value.empty()) {
-      throw CacheXmlException("XML:Value for attribute <" + name +
-                              "> needs to be specified in the "
-                              "<property>");
-    }
+  if (config_ == nullptr) {
+    config_ = Properties::create();
+  }
 
-    if ("name" == name) {
-      propName = value;
-    } else if ("value" == name) {
-      propValue = value;
-    } else {
-      throw CacheXmlException(
-          "XML:Incorrect attribute name specified in <property>: " + name);
-    }
-  }
-  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);
+  config_->insert(propertyName, propertyValue);
 }
 
-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>");
-  }
+void CacheXmlParser::startCacheLoader(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
 
-  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>");
-    }
-
-    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>");
-  }
-
-  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>");
-  }
+void CacheXmlParser::startCacheListener(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
 
-  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>");
-  }
-
-  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 +1116,12 @@
                                                 libraryFunctionName);
 }
 
-void CacheXmlParser::startCacheWriter(const xmlChar** atts) {
-  if (!atts) {
-    throw CacheXmlException("XML:No attributes provided for <cache-writer>");
-  }
+void CacheXmlParser::startCacheWriter(const xercesc::Attributes &attrs) {
+  auto libraryName = getLibraryName(attrs);
+  auto libraryFunctionName = getLibraryFunctionName(attrs);
 
-  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>");
-  }
-
-  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 +1133,20 @@
  * _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 +1154,9 @@
     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 +1169,7 @@
  * 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 +1183,7 @@
       std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
   regionAttributesFactory->setRegionTimeToLive(expireAttr->getAction(),
                                                expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1429,7 +1193,7 @@
  * attributes are assigned.
  */
 void CacheXmlParser::endRegionIdleTime() {
-  if (!m_flagExpirationAttribute) {
+  if (!flagExpirationAttribute_) {
     throw CacheXmlException(
         "XML: <region-idle-time> cannot be without <expiration-attributes>");
   }
@@ -1441,7 +1205,7 @@
 
   regionAttributesFactory->setRegionIdleTimeout(expireAttr->getAction(),
                                                 expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1451,7 +1215,7 @@
  * 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 +1227,7 @@
 
   regionAttributesFactory->setEntryTimeToLive(expireAttr->getAction(),
                                               expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1473,7 +1237,7 @@
  * attributes are assigned.
  */
 void CacheXmlParser::endEntryIdleTime() {
-  if (!m_flagExpirationAttribute) {
+  if (!flagExpirationAttribute_) {
     throw CacheXmlException(
         "XML: <entry-idle-time> cannot be without <expiration-attributes>");
   }
@@ -1485,7 +1249,7 @@
   // TODO GEODE-3136: consider string parser here.
   regionAttributesFactory->setEntryIdleTimeout(expireAttr->getAction(),
                                                expireAttr->getTimeout());
-  m_flagExpirationAttribute = false;
+  flagExpirationAttribute_ = false;
 }
 
 /**
@@ -1501,21 +1265,17 @@
   _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 @@
 
 // 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);
+template <typename T>
+using FactoryLoaderFn = std::function<T*(const char*, const char*)>;
 
-class APACHE_GEODE_EXPORT CacheXmlParser : public CacheXml {
+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;
+  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* m_cache;
-  /** Pool helper */
-  void setPoolInfo(PoolFactory* poolFactory, const char* name,
-                   const char* value);
-
-  void handleParserErrors(int res);
+  Cache* cache_;
 
  public:
   explicit CacheXmlParser(Cache* cache);
@@ -86,75 +86,89 @@
   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/ConcurrentEntriesMap.cpp b/cppcache/src/ConcurrentEntriesMap.cpp
index 090e560..b1983f4 100644
--- a/cppcache/src/ConcurrentEntriesMap.cpp
+++ b/cppcache/src/ConcurrentEntriesMap.cpp
@@ -39,8 +39,6 @@
       m_region(region),
       m_numDestroyTrackers(0),
       m_concurrencyChecksEnabled(concurrencyChecksEnabled) {
-  GF_DEV_ASSERT(entryFactory != nullptr);
-
   uint8_t maxConcurrency = TableOfPrimes::getMaxPrimeForConcurrency();
   if (concurrency > maxConcurrency) {
     m_concurrency = maxConcurrency;
diff --git a/cppcache/src/CppCacheLibrary.cpp b/cppcache/src/CppCacheLibrary.cpp
index ada5d08..3a68cee 100644
--- a/cppcache/src/CppCacheLibrary.cpp
+++ b/cppcache/src/CppCacheLibrary.cpp
@@ -103,7 +103,6 @@
   }
 
   // check if bin on windows, and go back one...
-  GF_D_ASSERT(productLibraryDirectoryName.length() > 4);
 #ifdef WIN32
   std::string libpart = "bin";
 #else
diff --git a/cppcache/src/CqQueryImpl.cpp b/cppcache/src/CqQueryImpl.cpp
index a7eadf8..53aa8cd 100644
--- a/cppcache/src/CqQueryImpl.cpp
+++ b/cppcache/src/CqQueryImpl.cpp
@@ -273,7 +273,6 @@
   err = m_tccdm->sendRequestToEP(request, reply, endpoint);
 
   if (err != GF_NOERR) {
-    // GfErrTypeToException("CqQuery::execute(endpoint)", err);
     return err;
   }
 
@@ -330,7 +329,7 @@
   GfErrType err = GF_NOERR;
   err = m_tccdm->sendSyncRequest(msg, reply);
   if (err != GF_NOERR) {
-    GfErrTypeToException("CqQuery::executeCq:", err);
+    throwExceptionIfError("CqQuery::executeCq:", err);
   }
   if (reply.getMessageType() == TcrMessage::EXCEPTION ||
       reply.getMessageType() == TcrMessage::CQDATAERROR_MSG_TYPE ||
@@ -342,7 +341,7 @@
           std::string("CqQuery::executeCq: exception at the server side: ") +
           reply.getException());
     } else {
-      GfErrTypeToException("CqQuery::executeCq", err);
+      throwExceptionIfError("CqQuery::executeCq", err);
     }
   }
   std::lock_guard<decltype(m_mutex)> _guard(m_mutex);
@@ -387,7 +386,7 @@
   err = m_tccdm->sendSyncRequest(msg, reply);
   if (err != GF_NOERR) {
     LOGDEBUG("CqQueryImpl::executeCqWithInitialResults errorred!!!!");
-    GfErrTypeToException("CqQuery::executeCqWithInitialResults:", err);
+    throwExceptionIfError("CqQuery::executeCqWithInitialResults:", err);
   }
   if (reply.getMessageType() == TcrMessage::EXCEPTION ||
       reply.getMessageType() == TcrMessage::CQDATAERROR_MSG_TYPE ||
@@ -399,7 +398,7 @@
           std::string("CqQuery::executeWithInitialResults: exception ") +
           "at the server side: " + reply.getException());
     } else {
-      GfErrTypeToException("CqQuery::executeWithInitialResults", err);
+      throwExceptionIfError("CqQuery::executeWithInitialResults", err);
     }
   }
   m_cqState = CqState::RUNNING;
@@ -478,7 +477,7 @@
   }
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("CqQuery::stop/close:", err);
+    throwExceptionIfError("CqQuery::stop/close:", err);
   }
   if (reply.getMessageType() == TcrMessage::EXCEPTION ||
       reply.getMessageType() == TcrMessage::CQDATAERROR_MSG_TYPE ||
@@ -490,7 +489,7 @@
           std::string("CqQuery::stop/close: exception at the server side: ") +
           reply.getException());
     } else {
-      GfErrTypeToException("CqQuery::stop/close", err);
+      throwExceptionIfError("CqQuery::stop/close", err);
     }
   }
 }
diff --git a/cppcache/src/CqService.cpp b/cppcache/src/CqService.cpp
index e872554..167ead0 100644
--- a/cppcache/src/CqService.cpp
+++ b/cppcache/src/CqService.cpp
@@ -559,7 +559,7 @@
   err = m_tccdm->sendSyncRequest(msg, reply);
   if (err != GF_NOERR) {
     LOGDEBUG("CqService::getAllDurableCqsFromServer!!!!");
-    GfErrTypeToException("CqService::getAllDurableCqsFromServer:", err);
+    throwExceptionIfError("CqService::getAllDurableCqsFromServer:", err);
   }
   if (reply.getMessageType() == TcrMessage::EXCEPTION ||
       reply.getMessageType() == TcrMessage::GET_DURABLE_CQS_DATA_ERROR) {
@@ -571,7 +571,7 @@
               << "at the server side: " << reply.getException();
       throw CqQueryException(message.str());
     } else {
-      GfErrTypeToException("CqService::getAllDurableCqsFromServer", err);
+      throwExceptionIfError("CqService::getAllDurableCqsFromServer", err);
     }
   }
 
diff --git a/cppcache/src/ErrType.hpp b/cppcache/src/ErrType.hpp
index bf8520d..6865a95 100644
--- a/cppcache/src/ErrType.hpp
+++ b/cppcache/src/ErrType.hpp
@@ -40,7 +40,7 @@
   GF_NOTSUP = 12,         /**< operation not supported          */
   GF_SCPGBL = 13,         /**< attempt to exit global scope     */
   GF_SCPEXC = 14,         /**< maximum scopes exceeded          */
-  GF_TIMOUT = 15,         /**< operation timed out              */
+  GF_TIMEOUT = 15,        /**< operation timed out              */
   GF_OVRFLW = 16,         /**< arithmetic overflow              */
   GF_IOERR = 17,          /**< paging file I/O error            */
   GF_EINTR = 18,          /**< interrupted Geode call         */
diff --git a/cppcache/src/ExceptionTypes.cpp b/cppcache/src/ExceptionTypes.cpp
index 366d189..2f31d17 100644
--- a/cppcache/src/ExceptionTypes.cpp
+++ b/cppcache/src/ExceptionTypes.cpp
@@ -165,7 +165,7 @@
       setThreadLocalExceptionMessage(nullptr);
       throw ex;
     }
-    case GF_TIMOUT: {
+    case GF_TIMEOUT: {
       message.append(!exMsg.empty() ? exMsg : ": timed out");
       TimeoutException ex(message);
       setThreadLocalExceptionMessage(nullptr);
diff --git a/cppcache/src/ExecutionImpl.cpp b/cppcache/src/ExecutionImpl.cpp
index bf5dc11..4dcb20e 100644
--- a/cppcache/src/ExecutionImpl.cpp
+++ b/cppcache/src/ExecutionImpl.cpp
@@ -119,7 +119,7 @@
           err = getFuncAttributes(func, &attr);
         }
         if (err != GF_NOERR) {
-          GfErrTypeToException("Execute::GET_FUNCTION_ATTRIBUTES", err);
+          throwExceptionIfError("Execute::GET_FUNCTION_ATTRIBUTES", err);
         }
         if (!attr->empty() && err == GF_NOERR) {
           m_func_attrs[func] = attr;
@@ -437,14 +437,14 @@
       throw FunctionExecutionException(
           "Execute: failed to execute function with server.");
     } else {
-      GfErrTypeToException("Execute", err);
+      throwExceptionIfError("Execute", err);
     }
   }
 
   if (err == GF_AUTHENTICATION_FAILED_EXCEPTION ||
       err == GF_NOT_AUTHORIZED_EXCEPTION ||
       err == GF_AUTHENTICATION_REQUIRED_EXCEPTION) {
-    GfErrTypeToException("Execute", err);
+    throwExceptionIfError("Execute", err);
   }
 
   if (err != GF_NOERR) {
@@ -515,7 +515,7 @@
                                                     reply.getException());
     }
     if (ThinClientBaseDM::isFatalClientError(err)) {
-      GfErrTypeToException("ExecuteOnPool:", err);
+      throwExceptionIfError("ExecuteOnPool:", err);
     } else if (err != GF_NOERR) {
       if (getResult & 1) {
         resultCollector->reset();
@@ -527,7 +527,7 @@
         }
         continue;
       } else {
-        GfErrTypeToException("ExecuteOnPool:", err);
+        throwExceptionIfError("ExecuteOnPool:", err);
       }
     }
     // auto values =
diff --git a/cppcache/src/ExpiryTaskManager.cpp b/cppcache/src/ExpiryTaskManager.cpp
index f5348ac..d7b90d5 100644
--- a/cppcache/src/ExpiryTaskManager.cpp
+++ b/cppcache/src/ExpiryTaskManager.cpp
@@ -17,7 +17,6 @@
 
 #include "ExpiryTaskManager.hpp"
 
-#include "Assert.hpp"
 #include "DistributedSystem.hpp"
 #include "DistributedSystemImpl.hpp"
 #include "config.h"
@@ -80,7 +79,6 @@
   if (m_reactorEventLoopRunning) {
     m_reactor->end_reactor_event_loop();
     this->wait();
-    GF_D_ASSERT(m_reactor->reactor_event_loop_done() > 0);
     m_reactorEventLoopRunning = false;
     m_condition.notify_all();
   }
diff --git a/cppcache/src/FairQueue.hpp b/cppcache/src/FairQueue.hpp
index 0cadce5..7e038c6 100644
--- a/cppcache/src/FairQueue.hpp
+++ b/cppcache/src/FairQueue.hpp
@@ -29,7 +29,6 @@
 #include <ace/Time_Value.h>
 #include <ace/Token.h>
 
-#include "Assert.hpp"
 #include "util/Log.hpp"
 
 namespace apache {
@@ -64,8 +63,6 @@
   }
 
   void put(T* mp, bool openQueue) {
-    GF_DEV_ASSERT(mp != 0);
-
     bool delMp = false;
     {
       ACE_Guard<MUTEX> _guard(m_queueLock);
diff --git a/cppcache/src/InternalCacheTransactionManager2PC.cpp b/cppcache/src/InternalCacheTransactionManager2PC.cpp
deleted file mode 100644
index f511acb..0000000
--- a/cppcache/src/InternalCacheTransactionManager2PC.cpp
+++ /dev/null
@@ -1,27 +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 "InternalCacheTransactionManager2PC.hpp"
-
-namespace apache {
-namespace geode {
-namespace client {
-InternalCacheTransactionManager2PC::InternalCacheTransactionManager2PC() {}
-InternalCacheTransactionManager2PC::~InternalCacheTransactionManager2PC() {}
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
diff --git a/cppcache/src/InternalCacheTransactionManager2PC.hpp b/cppcache/src/InternalCacheTransactionManager2PC.hpp
deleted file mode 100644
index c88c258..0000000
--- a/cppcache/src/InternalCacheTransactionManager2PC.hpp
+++ /dev/null
@@ -1,75 +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.
- */
-
-#pragma once
-
-#ifndef GEODE_INTERNALCACHETRANSACTIONMANAGER2PC_H_
-#define GEODE_INTERNALCACHETRANSACTIONMANAGER2PC_H_
-
-#include <geode/CacheTransactionManager.hpp>
-
-namespace apache {
-namespace geode {
-namespace client {
-
-/**
- * Extension of the apache::geode::client::CacheTransactionManager that enables
- * client
- * application
- * to use Geode transaction as part of the global XA transaction.
- *
- * The prepare method of this class corresponds to the prepare phases of the
- * 2 phase commit protocol driven by a global transaction manager.
- *
- * The implementation of the apache::geode::client::CacheTransactionManager
- * commit() and
- * rollback()
- * methods must be 2 phase commit process aware.
- *
- * Methods of this class are expected to be called by a custom XA Resource
- * Manager
- * that is wrapping and adapting Geode client to XA specification
- * requirements.
- *
- * @since 8.3
- *
- */
-class APACHE_GEODE_EXPORT InternalCacheTransactionManager2PC
-    : public virtual CacheTransactionManager {
- public:
-  /**
-   * Performs prepare during 2 phase commit completion.
-   * Locks of the entries modified in the current transaction on the server
-   * side.
-   *
-   * Calls to subsequent commit() or rollback() methods overridden by this class
-   * are
-   * expected to succeed after prepare() has returned successfully.
-   * Geode commits internal transaction irreversibly on commit() call.
-   *
-   */
-  virtual void prepare() = 0;
-
- protected:
-  InternalCacheTransactionManager2PC();
-  virtual ~InternalCacheTransactionManager2PC();
-};
-}  // namespace client
-}  // namespace geode
-}  // namespace apache
-
-#endif  // GEODE_INTERNALCACHETRANSACTIONMANAGER2PC_H_
diff --git a/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp b/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp
index 98d8388..facc842 100644
--- a/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp
+++ b/cppcache/src/InternalCacheTransactionManager2PCImpl.cpp
@@ -139,8 +139,8 @@
     }
 
     if (!txState->isPrepared()) {
-      // Fallback to deafult 1PC commit
-      // The inherited 1PC implmentation clears the transaction state
+      // Fallback to default 1PC commit
+      // The inherited 1PC implementation clears the transaction state
       switch (status) {
         case STATUS_COMMITTED:
           CacheTransactionManagerImpl::commit();
diff --git a/cppcache/src/InternalCacheTransactionManager2PCImpl.hpp b/cppcache/src/InternalCacheTransactionManager2PCImpl.hpp
index e5fdc8f..d2e453f 100644
--- a/cppcache/src/InternalCacheTransactionManager2PCImpl.hpp
+++ b/cppcache/src/InternalCacheTransactionManager2PCImpl.hpp
@@ -21,15 +21,13 @@
 #define GEODE_INTERNALCACHETRANSACTIONMANAGER2PCIMPL_H_
 
 #include "CacheTransactionManagerImpl.hpp"
-#include "InternalCacheTransactionManager2PC.hpp"
 
 namespace apache {
 namespace geode {
 namespace client {
 
 class InternalCacheTransactionManager2PCImpl
-    : public CacheTransactionManagerImpl,
-      public InternalCacheTransactionManager2PC {
+    : public CacheTransactionManagerImpl {
  public:
   explicit InternalCacheTransactionManager2PCImpl(CacheImpl* cache);
   virtual ~InternalCacheTransactionManager2PCImpl() override;
diff --git a/cppcache/src/LRUEntriesMap.cpp b/cppcache/src/LRUEntriesMap.cpp
index 394f5fe..ff43cd9 100644
--- a/cppcache/src/LRUEntriesMap.cpp
+++ b/cppcache/src/LRUEntriesMap.cpp
@@ -260,8 +260,6 @@
                              std::shared_ptr<VersionTag> versionTag,
                              bool& isUpdate, DataInput* delta) {
   MapSegment* segmentRPtr = segmentFor(key);
-  GF_D_ASSERT(segmentRPtr != nullptr);
-
   GfErrType err = GF_NOERR;
   bool segmentLocked = false;
   {
@@ -322,7 +320,7 @@
       segmentRPtr->getEntry(key, mePtr, tmpValue);
       // mePtr cannot be null, we just put it...
       // must convert to an std::shared_ptr<LRUMapEntryImpl>...
-      GF_D_ASSERT(mePtr != nullptr);
+
       m_lruList.appendEntry(mePtr);
       me = mePtr;
     } else {
diff --git a/cppcache/src/LRUList.cpp b/cppcache/src/LRUList.cpp
index 2e2dc9c..8d16753 100644
--- a/cppcache/src/LRUList.cpp
+++ b/cppcache/src/LRUList.cpp
@@ -19,7 +19,6 @@
 
 #include <mutex>
 
-#include "Assert.hpp"
 #include "util/concurrent/spinlock_mutex.hpp"
 
 namespace apache {
@@ -61,8 +60,6 @@
 void LRUList<TEntry, TCreateEntry>::appendNode(LRUListNode* aNode) {
   std::lock_guard<spinlock_mutex> lk(m_tailLock);
 
-  GF_D_ASSERT(aNode != nullptr);
-
   aNode->clearNextLRUListNode();
   m_tailNode->setNextLRUListNode(aNode);
   m_tailNode = aNode;
diff --git a/cppcache/src/LocalRegion.cpp b/cppcache/src/LocalRegion.cpp
index 79e469d..07d45db 100644
--- a/cppcache/src/LocalRegion.cpp
+++ b/cppcache/src/LocalRegion.cpp
@@ -142,28 +142,28 @@
     const std::shared_ptr<Serializable>& aCallbackArgument) {
   GfErrType err =
       invalidateRegionNoThrow(aCallbackArgument, CacheEventFlags::NORMAL);
-  GfErrTypeToException("Region::invalidateRegion", err);
+  throwExceptionIfError("Region::invalidateRegion", err);
 }
 
 void LocalRegion::localInvalidateRegion(
     const std::shared_ptr<Serializable>& aCallbackArgument) {
   GfErrType err =
       invalidateRegionNoThrow(aCallbackArgument, CacheEventFlags::LOCAL);
-  GfErrTypeToException("Region::localInvalidateRegion", err);
+  throwExceptionIfError("Region::localInvalidateRegion", err);
 }
 
 void LocalRegion::destroyRegion(
     const std::shared_ptr<Serializable>& aCallbackArgument) {
   GfErrType err =
       destroyRegionNoThrow(aCallbackArgument, true, CacheEventFlags::NORMAL);
-  GfErrTypeToException("Region::destroyRegion", err);
+  throwExceptionIfError("Region::destroyRegion", err);
 }
 
 void LocalRegion::localDestroyRegion(
     const std::shared_ptr<Serializable>& aCallbackArgument) {
   GfErrType err =
       destroyRegionNoThrow(aCallbackArgument, true, CacheEventFlags::LOCAL);
-  GfErrTypeToException("Region::localDestroyRegion", err);
+  throwExceptionIfError("Region::localDestroyRegion", err);
 }
 
 void LocalRegion::tombstoneOperationNoThrow(
@@ -334,7 +334,7 @@
 
   // rptr = handleReplay(err, rptr);
 
-  GfErrTypeToException("Region::get", err);
+  throwExceptionIfError("Region::get", err);
 
   return rptr;
 }
@@ -350,7 +350,7 @@
   updateStatOpTime(m_regionStats->getStat(), m_regionStats->getPutTimeId(),
                    sampleStartNanos);
   //  handleReplay(err, nullptr);
-  GfErrTypeToException("Region::put", err);
+  throwExceptionIfError("Region::put", err);
 }
 
 void LocalRegion::localPut(
@@ -361,7 +361,7 @@
   std::shared_ptr<VersionTag> versionTag;
   GfErrType err = putNoThrow(key, value, aCallbackArgument, oldValue, -1,
                              CacheEventFlags::LOCAL, versionTag);
-  GfErrTypeToException("Region::localPut", err);
+  throwExceptionIfError("Region::localPut", err);
 }
 
 void LocalRegion::putAll(
@@ -374,7 +374,7 @@
   updateStatOpTime(m_regionStats->getStat(), m_regionStats->getPutAllTimeId(),
                    sampleStartNanos);
   // handleReplay(err, nullptr);
-  GfErrTypeToException("Region::putAll", err);
+  throwExceptionIfError("Region::putAll", err);
 }
 
 void LocalRegion::removeAll(
@@ -387,7 +387,7 @@
   GfErrType err = removeAllNoThrow(keys, aCallbackArgument);
   updateStatOpTime(m_regionStats->getStat(),
                    m_regionStats->getRemoveAllTimeId(), sampleStartNanos);
-  GfErrTypeToException("Region::removeAll", err);
+  throwExceptionIfError("Region::removeAll", err);
 }
 
 void LocalRegion::create(
@@ -398,7 +398,7 @@
   GfErrType err = createNoThrow(key, value, aCallbackArgument, -1,
                                 CacheEventFlags::NORMAL, versionTag);
   // handleReplay(err, nullptr);
-  GfErrTypeToException("Region::create", err);
+  throwExceptionIfError("Region::create", err);
 }
 
 void LocalRegion::localCreate(
@@ -408,7 +408,7 @@
   std::shared_ptr<VersionTag> versionTag;
   GfErrType err = createNoThrow(key, value, aCallbackArgument, -1,
                                 CacheEventFlags::LOCAL, versionTag);
-  GfErrTypeToException("Region::localCreate", err);
+  throwExceptionIfError("Region::localCreate", err);
 }
 
 void LocalRegion::invalidate(
@@ -418,7 +418,7 @@
   GfErrType err = invalidateNoThrow(key, aCallbackArgument, -1,
                                     CacheEventFlags::NORMAL, versionTag);
   //  handleReplay(err, nullptr);
-  GfErrTypeToException("Region::invalidate", err);
+  throwExceptionIfError("Region::invalidate", err);
 }
 
 void LocalRegion::localInvalidate(
@@ -427,7 +427,7 @@
   std::shared_ptr<VersionTag> versionTag;
   GfErrType err = invalidateNoThrow(keyPtr, aCallbackArgument, -1,
                                     CacheEventFlags::LOCAL, versionTag);
-  GfErrTypeToException("Region::localInvalidate", err);
+  throwExceptionIfError("Region::localInvalidate", err);
 }
 
 void LocalRegion::destroy(
@@ -438,7 +438,7 @@
   GfErrType err = destroyNoThrow(key, aCallbackArgument, -1,
                                  CacheEventFlags::NORMAL, versionTag);
   // handleReplay(err, nullptr);
-  GfErrTypeToException("Region::destroy", err);
+  throwExceptionIfError("Region::destroy", err);
 }
 
 void LocalRegion::localDestroy(
@@ -447,7 +447,7 @@
   std::shared_ptr<VersionTag> versionTag;
   GfErrType err = destroyNoThrow(key, aCallbackArgument, -1,
                                  CacheEventFlags::LOCAL, versionTag);
-  GfErrTypeToException("Region::localDestroy", err);
+  throwExceptionIfError("Region::localDestroy", err);
 }
 
 bool LocalRegion::remove(
@@ -463,7 +463,7 @@
   if (err == GF_NOERR) {
     result = true;
   } else if (err != GF_ENOENT && err != GF_CACHE_ENTRY_NOT_FOUND) {
-    GfErrTypeToException("Region::remove", err);
+    throwExceptionIfError("Region::remove", err);
   }
 
   return result;
@@ -480,7 +480,7 @@
   if (err == GF_NOERR) {
     result = true;
   } else if (err != GF_ENOENT && err != GF_CACHE_ENTRY_NOT_FOUND) {
-    GfErrTypeToException("Region::removeEx", err);
+    throwExceptionIfError("Region::removeEx", err);
   }
 
   return result;
@@ -499,7 +499,7 @@
   if (err == GF_NOERR) {
     result = true;
   } else if (err != GF_ENOENT && err != GF_CACHE_ENTRY_NOT_FOUND) {
-    GfErrTypeToException("Region::localRemove", err);
+    throwExceptionIfError("Region::localRemove", err);
   }
 
   return result;
@@ -517,7 +517,7 @@
   if (err == GF_NOERR) {
     result = true;
   } else if (err != GF_ENOENT && err != GF_CACHE_ENTRY_NOT_FOUND) {
-    GfErrTypeToException("Region::localRemoveEx", err);
+    throwExceptionIfError("Region::localRemoveEx", err);
   }
 
   return result;
@@ -582,7 +582,7 @@
   updateStatOpTime(m_regionStats->getStat(), m_regionStats->getGetAllTimeId(),
                    sampleStartNanos);
 
-  GfErrTypeToException("Region::getAll", err);
+  throwExceptionIfError("Region::getAll", err);
 
   return *values;
 }
@@ -2169,7 +2169,7 @@
 void LocalRegion::localClear(
     const std::shared_ptr<Serializable>& aCallbackArgument) {
   GfErrType err = localClearNoThrow(aCallbackArgument, CacheEventFlags::LOCAL);
-  if (err != GF_NOERR) GfErrTypeToException("LocalRegion::localClear", err);
+  if (err != GF_NOERR) throwExceptionIfError("LocalRegion::localClear", err);
 }
 GfErrType LocalRegion::localClearNoThrow(
     const std::shared_ptr<Serializable>& aCallbackArgument,
@@ -2419,7 +2419,6 @@
   if (m_regionAttributes.getCachingEnabled()) {
     _GEODE_SAFE_DELETE(m_entries);
   }
-  GF_D_ASSERT(m_destroyPending);
 
   if (removeFromParent) {
     if (m_parentRegion == nullptr) {
diff --git a/cppcache/src/Log.cpp b/cppcache/src/Log.cpp
index 93a2ffb..07d8362 100644
--- a/cppcache/src/Log.cpp
+++ b/cppcache/src/Log.cpp
@@ -44,7 +44,6 @@
 #include <geode/util/LogLevel.hpp>
 
 #include "../internal/hacks/AceThreadId.h"
-#include "Assert.hpp"
 #include "geodeBanner.hpp"
 #include "util/chrono/time_point.hpp"
 
@@ -413,7 +412,6 @@
     fflush(stdout);
     return;
   }  // else
-  GF_D_ASSERT(g_logFile && g_logMutex && g_logFileWithExt);
 
   if (fprintf(g_log, "%s", bannertext.c_str()) == 0 || ferror(g_log)) {
     // we should be continue,
diff --git a/cppcache/src/PoolManagerImpl.cpp b/cppcache/src/PoolManagerImpl.cpp
index 305668d..fc81a5d 100644
--- a/cppcache/src/PoolManagerImpl.cpp
+++ b/cppcache/src/PoolManagerImpl.cpp
@@ -62,7 +62,6 @@
 
     if (iter != m_connectionPools.end()) {
       poolPtr = iter->second;
-      GF_DEV_ASSERT(poolPtr != nullptr);
     }
 
     return poolPtr;
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 geode {
 namespace client {
 
+using apache::geode::client::Utils;
+
 RegionAttributes::RegionAttributes()
     : Serializable(),
       m_regionTimeToLiveExpirationAction(ExpirationAction::INVALIDATE),
@@ -59,41 +59,17 @@
 
 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<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<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<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<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/RegionXmlCreation.cpp b/cppcache/src/RegionXmlCreation.cpp
index aedd7f4..283fa97 100644
--- a/cppcache/src/RegionXmlCreation.cpp
+++ b/cppcache/src/RegionXmlCreation.cpp
@@ -44,7 +44,6 @@
 }
 
 void RegionXmlCreation::createRoot(Cache* cache) {
-  GF_D_ASSERT(this->isRoot);
   std::shared_ptr<Region> rootRegPtr = nullptr;
 
   CacheImpl* cacheImpl = CacheRegionHelper::getCacheImpl(cache);
@@ -53,7 +52,6 @@
 }
 
 void RegionXmlCreation::create(std::shared_ptr<Region> parent) {
-  GF_D_ASSERT(!(this->isRoot));
   std::shared_ptr<Region> subRegPtr = nullptr;
 
   subRegPtr = parent->createSubregion(regionName, regionAttributes);
diff --git a/cppcache/src/RemoteQuery.cpp b/cppcache/src/RemoteQuery.cpp
index fce5803..3a9abfe 100644
--- a/cppcache/src/RemoteQuery.cpp
+++ b/cppcache/src/RemoteQuery.cpp
@@ -82,7 +82,7 @@
   reply.setChunkedResultHandler(
       static_cast<TcrChunkedResult*>(resultCollector));
   GfErrType err = executeNoThrow(timeout, reply, func, tcdm, paramList);
-  GfErrTypeToException(func, err);
+  throwExceptionIfError(func, err);
 
   std::shared_ptr<SelectResults> sr;
 
diff --git a/cppcache/src/TcpConn.cpp b/cppcache/src/TcpConn.cpp
index ec88007..c8837c6 100644
--- a/cppcache/src/TcpConn.cpp
+++ b/cppcache/src/TcpConn.cpp
@@ -159,8 +159,6 @@
                      std::chrono::microseconds waitSeconds) {
   using apache::geode::internal::chrono::duration::to_string;
 
-  GF_DEV_ASSERT(m_io != nullptr);
-
   ACE_SOCK_Acceptor listener(addr, 1);
   int32_t retVal = 0;
   if (waitSeconds > std::chrono::microseconds::zero()) {
@@ -202,8 +200,6 @@
 void TcpConn::connect() {
   using apache::geode::internal::chrono::duration::to_string;
 
-  GF_DEV_ASSERT(m_io != nullptr);
-
   ACE_INET_Addr ipaddr = m_addr;
   std::chrono::microseconds waitMicroSeconds = m_waitMilliSeconds;
 
@@ -269,19 +265,6 @@
 size_t TcpConn::socketOp(TcpConn::SockOp op, char *buff, size_t len,
                          std::chrono::microseconds waitDuration) {
   {
-    GF_DEV_ASSERT(m_io != nullptr);
-    GF_DEV_ASSERT(buff != nullptr);
-
-#if GF_DEVEL_ASSERTS == 1
-    if (len <= 0) {
-      LOGERROR(
-          "TcpConn::socketOp called with a length of %d specified. "
-          "No operation performed.",
-          len);
-      GF_DEV_ASSERT(false);
-    }
-#endif
-
     ACE_Time_Value waitTime(waitDuration);
     auto endTime = std::chrono::steady_clock::now() + waitDuration;
     size_t readLen = 0;
@@ -333,15 +316,12 @@
       ACE_OS::last_error(ETIME);
     }
 
-    GF_DEV_ASSERT(len >= 0);
     return totalsend;
   }
 }
 
 //  Return the local port for this TCP connection.
 uint16_t TcpConn::getPort() {
-  GF_DEV_ASSERT(m_io != nullptr);
-
   ACE_INET_Addr localAddr;
   m_io->get_local_addr(localAddr);
   return localAddr.get_port_number();
diff --git a/cppcache/src/TcpConn.hpp b/cppcache/src/TcpConn.hpp
index 8fddb8a..888df84 100644
--- a/cppcache/src/TcpConn.hpp
+++ b/cppcache/src/TcpConn.hpp
@@ -26,7 +26,6 @@
 
 #include <geode/internal/geode_globals.hpp>
 
-#include "Assert.hpp"
 #include "Connector.hpp"
 #include "util/Log.hpp"
 
@@ -120,8 +119,6 @@
               std::chrono::microseconds waitSeconds) override;
 
   virtual void setOption(int32_t level, int32_t option, void* val, size_t len) {
-    GF_DEV_ASSERT(m_io != nullptr);
-
     if (m_io->set_option(level, option, val, static_cast<int32_t>(len)) == -1) {
       int32_t lastError = ACE_OS::last_error();
       LOGERROR("Failed to set option, errno: %d: %s", lastError,
diff --git a/cppcache/src/TcpSslConn.cpp b/cppcache/src/TcpSslConn.cpp
index 8712ad0..22b59aa 100644
--- a/cppcache/src/TcpSslConn.cpp
+++ b/cppcache/src/TcpSslConn.cpp
@@ -55,15 +55,17 @@
 
 void TcpSslConn::createSocket(ACE_HANDLE sock) {
   LOGDEBUG("Creating SSL socket stream");
-  m_ssl = getSSLImpl(sock, m_pubkeyfile, m_privkeyfile);
+  try {
+    m_ssl = getSSLImpl(sock, m_pubkeyfile, m_privkeyfile);
+  } catch (std::exception& e) {
+    throw SslException(e.what());
+  }
 }
 
 void TcpSslConn::listen(ACE_INET_Addr addr,
                         std::chrono::microseconds waitSeconds) {
   using apache::geode::internal::chrono::duration::to_string;
 
-  GF_DEV_ASSERT(m_ssl != nullptr);
-
   int32_t retVal = m_ssl->listen(addr, waitSeconds);
 
   if (retVal == -1) {
@@ -83,8 +85,6 @@
 void TcpSslConn::connect() {
   using apache::geode::internal::chrono::duration::to_string;
 
-  GF_DEV_ASSERT(m_ssl != nullptr);
-
   ACE_OS::signal(SIGPIPE, SIG_IGN);  // Ignore broken pipe
 
   // m_ssl->init();
@@ -128,18 +128,6 @@
 size_t TcpSslConn::socketOp(TcpConn::SockOp op, char* buff, size_t len,
                             std::chrono::microseconds waitDuration) {
   {
-    GF_DEV_ASSERT(m_ssl != nullptr);
-    GF_DEV_ASSERT(buff != nullptr);
-
-#if GF_DEVEL_ASSERTS == 1
-    if (len <= 0) {
-      LOGERROR(
-          "TcpSslConn::socketOp called with a length of %d specified. "
-          "No operation performed.",
-          len);
-      GF_DEV_ASSERT(false);
-    }
-#endif
     // passing wait time as micro seconds
     ACE_Time_Value waitTime(waitDuration);
     auto endTime = std::chrono::steady_clock::now() + waitDuration;
@@ -192,14 +180,11 @@
       ACE_OS::last_error(ETIME);
     }
 
-    GF_DEV_ASSERT(len >= 0);
     return totalsend;
   }
 }
 
 uint16_t TcpSslConn::getPort() {
-  GF_DEV_ASSERT(m_ssl != nullptr);
-
   ACE_INET_Addr localAddr;
   m_ssl->getLocalAddr(localAddr);
   return localAddr.get_port_number();
diff --git a/cppcache/src/TcpSslConn.hpp b/cppcache/src/TcpSslConn.hpp
index 02f3ea5..378c8c6 100644
--- a/cppcache/src/TcpSslConn.hpp
+++ b/cppcache/src/TcpSslConn.hpp
@@ -87,8 +87,6 @@
 
   void setOption(int32_t level, int32_t option, void* val,
                  size_t len) override {
-    GF_DEV_ASSERT(m_ssl != nullptr);
-
     if (m_ssl->setOption(level, option, val, static_cast<int32_t>(len)) == -1) {
       int32_t lastError = ACE_OS::last_error();
       LOGERROR("Failed to set option, errno: %d: %s", lastError,
diff --git a/cppcache/src/TcrChunkedContext.hpp b/cppcache/src/TcrChunkedContext.hpp
index e5df84c..17b42c6 100644
--- a/cppcache/src/TcrChunkedContext.hpp
+++ b/cppcache/src/TcrChunkedContext.hpp
@@ -111,6 +111,8 @@
   inline void setException(std::shared_ptr<Exception> ex) { m_ex = ex; }
 
   inline std::shared_ptr<Exception>& getException() { return m_ex; }
+
+  inline void clearException() { m_ex = nullptr; }
 };
 
 /**
@@ -119,37 +121,37 @@
  */
 class TcrChunkedContext {
  private:
-  const uint8_t* m_bytes;
+  const std::vector<uint8_t> m_chunk;
   const int32_t m_len;
   const uint8_t m_isLastChunkWithSecurity;
   const CacheImpl* m_cache;
   TcrChunkedResult* m_result;
 
  public:
-  inline TcrChunkedContext(const uint8_t* bytes, int32_t len,
+  inline TcrChunkedContext(const std::vector<uint8_t> chunk, int32_t len,
                            TcrChunkedResult* result,
                            uint8_t isLastChunkWithSecurity,
                            const CacheImpl* cacheImpl)
-      : m_bytes(bytes),
+      : m_chunk(chunk),
         m_len(len),
         m_isLastChunkWithSecurity(isLastChunkWithSecurity),
         m_cache(cacheImpl),
         m_result(result) {}
 
-  inline ~TcrChunkedContext() { _GEODE_SAFE_DELETE_ARRAY(m_bytes); }
+  inline ~TcrChunkedContext() = default;
 
-  inline const uint8_t* getBytes() const { return m_bytes; }
+  inline const uint8_t* getBytes() const { return m_chunk.data(); }
 
-  inline int32_t getLen() const { return m_len; }
+  inline size_t getLen() const { return m_chunk.size(); }
 
   void handleChunk(bool inSameThread) {
-    if (m_bytes == nullptr) {
+    if (m_chunk.empty()) {
       // this is the last chunk for some set of chunks
       m_result->finalize(inSameThread);
     } else if (!m_result->exceptionOccurred()) {
       try {
-        m_result->fireHandleChunk(m_bytes, m_len, m_isLastChunkWithSecurity,
-                                  m_cache);
+        m_result->fireHandleChunk(m_chunk.data(), m_len,
+                                  m_isLastChunkWithSecurity, m_cache);
       } catch (Exception& ex) {
         LOGERROR("HandleChunk error message %s, name = %s", ex.what(),
                  ex.getName().c_str());
diff --git a/cppcache/src/TcrConnection.cpp b/cppcache/src/TcrConnection.cpp
index b38bc25..b2882f7 100644
--- a/cppcache/src/TcrConnection.cpp
+++ b/cppcache/src/TcrConnection.cpp
@@ -17,7 +17,7 @@
 
 #include "TcrConnection.hpp"
 
-#include <memory.h>
+#include <cinttypes>
 
 #include <ace/INET_Addr.h>
 #include <ace/OS.h>
@@ -42,6 +42,8 @@
 namespace client {
 
 const int HEADER_LENGTH = 17;
+const int CHUNK_HEADER_LENGTH = 5;
+const int8_t LAST_CHUNK_MASK = 0x1;
 const int64_t INITIAL_CONNECTION_ID = 26739;
 
 #define throwException(ex)                            \
@@ -49,7 +51,22 @@
     LOGFINEST(ex.getName() + ": " + ex.getMessage()); \
     throw ex;                                         \
   }
-bool TcrConnection::InitTcrConnection(
+
+struct FinalizeProcessChunk {
+ private:
+  TcrMessage& m_reply;
+  uint16_t m_endpointMemId;
+
+ public:
+  FinalizeProcessChunk(TcrMessageReply& reply, uint16_t endpointMemId)
+      : m_reply(reply), m_endpointMemId(endpointMemId) {}
+  ~FinalizeProcessChunk() noexcept(false) {
+    // Enqueue a nullptr chunk indicating a wait for processing to complete.
+    m_reply.processChunk(std::vector<uint8_t>(), 0, m_endpointMemId);
+  }
+};
+
+bool TcrConnection::initTcrConnection(
     TcrEndpoint* endpointObj, const char* endpoint,
     synchronized_set<std::unordered_set<uint16_t>>& ports,
     bool isClientNotification, bool isSecondary,
@@ -78,13 +95,10 @@
       m_endpointObj->getConnRefCounter());
   bool isPool = false;
   m_isBeingUsed = false;
-  GF_DEV_ASSERT(endpoint != nullptr);
   m_endpoint = endpoint;
   // Precondition:
   // 1. isSecondary ==> isClientNotification
 
-  GF_DEV_ASSERT(!isSecondary || isClientNotification);
-
   // Create TcpConn object which manages a socket connection with the endpoint.
   if (endpointObj && endpointObj->getPoolHADM()) {
     m_conn = createConnection(
@@ -97,8 +111,6 @@
                               sysProp.maxSocketBufferSize());
   }
 
-  GF_DEV_ASSERT(m_conn != nullptr);
-
   auto handShakeMsg = cacheImpl->createDataOutput();
   bool isNotificationChannel = false;
   // Send byte Acceptor.CLIENT_TO_SERVER = (byte) 100;
@@ -127,7 +139,6 @@
     m_port = m_conn->getPort();
     ports.insert(m_port);
   } else {
-    // add the local ports to message
     auto&& lock = ports.make_lock();
     handShakeMsg.writeInt(static_cast<int32_t>(ports.size()));
     for (const auto& port : ports) {
@@ -579,9 +590,6 @@
 inline ConnErrType TcrConnection::receiveData(
     char* buffer, size_t length, std::chrono::microseconds receiveTimeoutSec,
     bool checkConnected, bool isNotificationMessage) {
-  GF_DEV_ASSERT(buffer != nullptr);
-  GF_DEV_ASSERT(m_conn != nullptr);
-
   std::chrono::microseconds defaultWaitSecs =
       isNotificationMessage ? std::chrono::seconds(1) : std::chrono::seconds(2);
   if (defaultWaitSecs > receiveTimeoutSec) defaultWaitSecs = receiveTimeoutSec;
@@ -620,8 +628,6 @@
     }
   }
   //  Postconditions for checking bounds.
-  GF_DEV_ASSERT(startLen >= length);
-  GF_DEV_ASSERT(length >= 0);
   return (length == 0 ? CONN_NOERR
                       : (length == startLen ? CONN_NODATA : CONN_TIMEOUT));
 }
@@ -636,9 +642,6 @@
 inline ConnErrType TcrConnection::sendData(
     std::chrono::microseconds& timeSpent, const char* buffer, size_t length,
     std::chrono::microseconds sendTimeout, bool checkConnected) {
-  GF_DEV_ASSERT(buffer != nullptr);
-  GF_DEV_ASSERT(m_conn != nullptr);
-
   std::chrono::microseconds defaultWaitSecs = std::chrono::seconds(2);
   if (defaultWaitSecs > sendTimeout) defaultWaitSecs = sendTimeout;
   LOGDEBUG(
@@ -695,36 +698,54 @@
     const TcrMessage& request, size_t len, TcrMessageReply& reply,
     std::chrono::microseconds sendTimeoutSec,
     std::chrono::microseconds receiveTimeoutSec) {
-  auto msgType = request.getMessageType();
-  switch (msgType) {
-    case TcrMessage::QUERY:
-    case TcrMessage::QUERY_WITH_PARAMETERS:
-    case TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE:
-    case TcrMessage::GETDURABLECQS_MSG_TYPE:
-    case TcrMessage::EXECUTE_FUNCTION:
-    case TcrMessage::EXECUTE_REGION_FUNCTION:
-    case TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP: {
-      receiveTimeoutSec = reply.getTimeout();
-      sendTimeoutSec = reply.getTimeout();
-      break;
-    }
-    default:
-      break;
+  if (useReplyTimeout(request)) {
+    receiveTimeoutSec = reply.getTimeout();
+    sendTimeoutSec = reply.getTimeout();
   }
 
-  std::chrono::microseconds timeSpent{0};
-  send(timeSpent, request.getMsgData(), len, sendTimeoutSec, true);
-
-  if (timeSpent >= receiveTimeoutSec)
-    throwException(
-        TimeoutException("TcrConnection::send: connection timed out"));
-
-  receiveTimeoutSec -= timeSpent;
+  receiveTimeoutSec -= sendWithTimeouts(request.getMsgData(), len,
+                                        sendTimeoutSec, receiveTimeoutSec);
 
   // to help in decoding the reply based on what was the request type
-  reply.setMessageTypeRequest(msgType);
+  reply.setMessageTypeRequest(request.getMessageType());
+
+  if (replyHasResult(request, reply)) {
+    readMessageChunked(reply, receiveTimeoutSec, true);
+  }
+}
+
+bool TcrConnection::useReplyTimeout(const TcrMessage& request) const {
+  auto messageType = request.getMessageType();
+  return ((messageType == TcrMessage::QUERY) ||
+          (messageType == TcrMessage::QUERY_WITH_PARAMETERS) ||
+          (messageType == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE) ||
+          (messageType == TcrMessage::GETDURABLECQS_MSG_TYPE) ||
+          (messageType == TcrMessage::EXECUTE_FUNCTION) ||
+          (messageType == TcrMessage::EXECUTE_REGION_FUNCTION) ||
+          (messageType == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP));
+}
+
+std::chrono::microseconds TcrConnection::sendWithTimeouts(
+    const char* data, size_t len, std::chrono::microseconds sendTimeout,
+    std::chrono::microseconds receiveTimeout) {
+  std::chrono::microseconds timeSpent{0};
+  send(timeSpent, data, len, sendTimeout, true);
+
+  if (timeSpent >= receiveTimeout) {
+    throwException(
+        TimeoutException("TcrConnection::send: connection timed out"));
+  }
+
+  return timeSpent;
+}
+
+bool TcrConnection::replyHasResult(const TcrMessage& request,
+                                   TcrMessageReply& reply) {
+  auto hasResult = true;
+
   // no need of it now, this will not come here
-  if (msgType == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP) {
+  if (request.getMessageType() ==
+      TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP) {
     ChunkedFunctionExecutionResponse* resultCollector =
         static_cast<ChunkedFunctionExecutionResponse*>(
             reply.getChunkedResultHandler());
@@ -732,10 +753,11 @@
       LOGDEBUG(
           "TcrConnection::sendRequestForChunkedResponse: function execution, "
           "no response desired");
-      return;
+      hasResult = false;
     }
   }
-  readMessageChunked(reply, receiveTimeoutSec, true);
+
+  return hasResult;
 }
 
 void TcrConnection::send(const char* buffer, size_t len,
@@ -748,8 +770,6 @@
 void TcrConnection::send(std::chrono::microseconds& timeSpent,
                          const char* buffer, size_t len,
                          std::chrono::microseconds sendTimeoutSec, bool) {
-  GF_DEV_ASSERT(m_conn != nullptr);
-
   // LOGINFO("TcrConnection::send: [%p] sending request to endpoint %s;",
   //:  this, m_endpoint);
 
@@ -777,8 +797,6 @@
 
 char* TcrConnection::receive(size_t* recvLen, ConnErrType* opErr,
                              std::chrono::microseconds receiveTimeoutSec) {
-  GF_DEV_ASSERT(m_conn != nullptr);
-
   return readMessage(recvLen, receiveTimeoutSec, false, opErr, true);
 }
 
@@ -850,7 +868,6 @@
     return fullMessage;
     // exit(0);
   }
-  // GF_DEV_ASSERT(msgLen > 0);
 
   // user has to delete this pointer
   char* fullMessage;
@@ -895,145 +912,45 @@
   return fullMessage;
 }
 
-void TcrConnection::readMessageChunked(
-    TcrMessageReply& reply, std::chrono::microseconds receiveTimeoutSec,
-    bool doHeaderTimeoutRetries) {
-  const int HDR_LEN = 5;
-  const int HDR_LEN_12 = 12;
-  uint8_t msg_header[HDR_LEN_12 + HDR_LEN];
-  ConnErrType error;
-
-  std::chrono::microseconds headerTimeout = receiveTimeoutSec;
-  if (doHeaderTimeoutRetries &&
-      receiveTimeoutSec == DEFAULT_READ_TIMEOUT_SECS) {
-    headerTimeout = DEFAULT_READ_TIMEOUT_SECS * DEFAULT_TIMEOUT_RETRIES;
-  }
+void TcrConnection::readMessageChunked(TcrMessageReply& reply,
+                                       std::chrono::microseconds receiveTimeout,
+                                       bool doHeaderTimeoutRetries) {
+  auto headerTimeout =
+      calculateHeaderTimeout(receiveTimeout, doHeaderTimeoutRetries);
 
   LOGFINER(
       "TcrConnection::readMessageChunked: receiving reply from "
       "endpoint %s",
       m_endpoint);
 
-  error = receiveData(reinterpret_cast<char*>(msg_header), HDR_LEN_12 + HDR_LEN,
-                      headerTimeout, true, false);
-  if (error != CONN_NOERR) {
-    if (error & CONN_TIMEOUT) {
-      throwException(TimeoutException(
-          "TcrConnection::readMessageChunked: "
-          "connection timed out while receiving message header"));
-    } else {
-      throwException(GeodeIOException(
-          "TcrConnection::readMessageChunked: "
-          "connection failure while receiving message header"));
-    }
-  }
+  auto responseHeader = readResponseHeader(headerTimeout);
 
-  LOGDEBUG(
-      "TcrConnection::readMessageChunked: received header from "
-      "endpoint %s; bytes: %s",
-      m_endpoint, Utils::convertBytesToString(msg_header, HDR_LEN_12).c_str());
-
-  auto input = m_connectionManager->getCacheImpl()->createDataInput(msg_header,
-                                                                    HDR_LEN_12);
-  int32_t msgType = input.readInt32();
-  reply.setMessageType(msgType);
-  int32_t txId;
-  int32_t numOfParts = input.readInt32();
-  LOGDEBUG("TcrConnection::readMessageChunked numberof parts = %d ",
-           numOfParts);
-  // input->advanceCursor(4);
-  txId = input.readInt32();
-  reply.setTransId(txId);
-
-  // bool isLastChunk = false;
-  uint8_t isLastChunk = 0x0;
-
-  int chunkNum = 0;
+  reply.setMessageType(responseHeader.messageType);
+  reply.setTransId(responseHeader.transactionId);
 
   // Initialize the chunk processing
   reply.startProcessChunk(m_chunksProcessSema);
 
-  //  indicate an end to chunk processing and wait for processing
+  // indicate an end to chunk processing and wait for processing
   // to end even if reading the chunks fails in middle
-  struct FinalizeProcessChunk {
-   private:
-    TcrMessage& m_reply;
-    uint16_t m_endpointmemId;
+  FinalizeProcessChunk endProcessChunk(reply,
+                                       m_endpointObj->getDistributedMemberID());
 
-   public:
-    FinalizeProcessChunk(TcrMessageReply& reply, uint16_t endpointmemId)
-        : m_reply(reply), m_endpointmemId(endpointmemId) {}
-    ~FinalizeProcessChunk() {
-      // Enqueue a nullptr chunk indicating a wait for processing to complete.
-      m_reply.processChunk(nullptr, 0, m_endpointmemId);
+  auto header = responseHeader.header;
+  try {
+    while (
+        processChunk(reply, receiveTimeout, header.chunkLength, header.flags)) {
+      header = readChunkHeader(headerTimeout);
     }
-  } endProcessChunk(reply, m_endpointObj->getDistributedMemberID());
-  bool first = true;
-  do {
-    // uint8_t chunk_header[HDR_LEN];
-    if (!first) {
-      error = receiveData(reinterpret_cast<char*>(msg_header + HDR_LEN_12),
-                          HDR_LEN, headerTimeout, true, false);
-      if (error != CONN_NOERR) {
-        if (error & CONN_TIMEOUT) {
-          throwException(TimeoutException(
-              "TcrConnection::readMessageChunked: "
-              "connection timed out while receiving chunk header"));
-        } else {
-          throwException(GeodeIOException(
-              "TcrConnection::readMessageChunked: "
-              "connection failure while receiving chunk header"));
-        }
-      }
-    } else {
-      first = false;
-    }
-    ++chunkNum;
-
-    LOGDEBUG(
-        "TcrConnection::readMessageChunked: received chunk header %d "
-        "from endpoint %s; bytes: %s",
-        chunkNum, m_endpoint,
-        Utils::convertBytesToString((msg_header + HDR_LEN_12), HDR_LEN)
-
-            .c_str());
-
-    auto input = m_connectionManager->getCacheImpl()->createDataInput(
-        msg_header + HDR_LEN_12, HDR_LEN);
-    int32_t chunkLen;
-    chunkLen = input.readInt32();
-    //  check that chunk length is valid.
-    GF_DEV_ASSERT(chunkLen > 0);
-    isLastChunk = input.read();
-
-    uint8_t* chunk_body;
-    _GEODE_NEW(chunk_body, uint8_t[chunkLen]);
-    error = receiveData(reinterpret_cast<char*>(chunk_body), chunkLen,
-                        receiveTimeoutSec, true, false);
-    if (error != CONN_NOERR) {
-      delete[] chunk_body;
-      if (error & CONN_TIMEOUT) {
-        throwException(TimeoutException(
-            "TcrConnection::readMessageChunked: "
-            "connection timed out while receiving chunk body"));
-      } else {
-        throwException(
-            GeodeIOException("TcrConnection::readMessageChunked: "
-                             "connection failure while receiving chunk body"));
+  } catch (const Exception&) {
+    if (auto handler = reply.getChunkedResultHandler()) {
+      if (auto ex = handler->getException()) {
+        LOGDEBUG("Found existing exception ", ex->what());
+        handler->clearException();
       }
     }
-
-    LOGDEBUG(
-        "TcrConnection::readMessageChunked: received chunk body %d "
-        "from endpoint %s; bytes: %s",
-        chunkNum, m_endpoint,
-        Utils::convertBytesToString(chunk_body, chunkLen).c_str());
-    // Process the chunk; the actual processing is done by a separate thread
-    // ThinClientBaseDM::m_chunkProcessor.
-
-    reply.processChunk(chunk_body, chunkLen,
-                       m_endpointObj->getDistributedMemberID(), isLastChunk);
-  } while (!(isLastChunk & 0x1));
+    throw;
+  }
 
   LOGFINER(
       "TcrConnection::readMessageChunked: read full reply "
@@ -1041,6 +958,138 @@
       m_endpoint);
 }
 
+std::chrono::microseconds TcrConnection::calculateHeaderTimeout(
+    std::chrono::microseconds receiveTimeout, bool retry) {
+  auto headerTimeout = receiveTimeout;
+  if (retry && receiveTimeout == DEFAULT_READ_TIMEOUT_SECS) {
+    headerTimeout *= DEFAULT_TIMEOUT_RETRIES;
+  }
+  return headerTimeout;
+}
+
+chunkedResponseHeader TcrConnection::readResponseHeader(
+    std::chrono::microseconds timeout) {
+  uint8_t receiveBuffer[HEADER_LENGTH];
+  chunkedResponseHeader header;
+
+  auto error = receiveData(reinterpret_cast<char*>(receiveBuffer),
+                           HEADER_LENGTH, timeout, true, false);
+  if (error != CONN_NOERR) {
+    if (error & CONN_TIMEOUT) {
+      throwException(TimeoutException(
+          "TcrConnection::readResponseHeader: "
+          "connection timed out while receiving message header"));
+    } else {
+      throwException(GeodeIOException(
+          "TcrConnection::readResponseHeader: "
+          "connection failure while receiving message header"));
+    }
+  }
+
+  LOGDEBUG(
+      "TcrConnection::readResponseHeader: received header from "
+      "endpoint %s; bytes: %s",
+      m_endpoint,
+      Utils::convertBytesToString(receiveBuffer, HEADER_LENGTH).c_str());
+
+  auto input = m_connectionManager->getCacheImpl()->createDataInput(
+      receiveBuffer, HEADER_LENGTH);
+  header.messageType = input.readInt32();
+  header.numberOfParts = input.readInt32();
+  header.transactionId = input.readInt32();
+  header.header.chunkLength = input.readInt32();
+  header.header.flags = input.read();
+  LOGDEBUG(
+      "TcrConnection::readResponseHeader: "
+      "messageType=%" PRId32 ", numberOfParts=%" PRId32
+      ", transactionId=%" PRId32 ", chunkLength=%" PRId32
+      ", lastChunkAndSecurityFlags=0x%" PRIx8,
+      header.messageType, header.numberOfParts, header.transactionId,
+      header.header.chunkLength, header.header.flags);
+
+  return header;
+}  // namespace client
+
+chunkHeader TcrConnection::readChunkHeader(std::chrono::microseconds timeout) {
+  uint8_t receiveBuffer[CHUNK_HEADER_LENGTH];
+  chunkHeader header;
+
+  auto error = receiveData(reinterpret_cast<char*>(receiveBuffer),
+                           CHUNK_HEADER_LENGTH, timeout, true, false);
+  if (error != CONN_NOERR) {
+    if (error & CONN_TIMEOUT) {
+      throwException(TimeoutException(
+          "TcrConnection::readChunkHeader: "
+          "connection timed out while receiving message header"));
+    } else {
+      throwException(GeodeIOException(
+          "TcrConnection::readChunkHeader: "
+          "connection failure while receiving message header"));
+    }
+  }
+
+  LOGDEBUG(
+      "TcrConnection::readChunkHeader: received header from "
+      "endpoint %s; bytes: %s",
+      m_endpoint,
+      Utils::convertBytesToString(receiveBuffer, CHUNK_HEADER_LENGTH).c_str());
+
+  auto input = m_connectionManager->getCacheImpl()->createDataInput(
+      receiveBuffer, CHUNK_HEADER_LENGTH);
+  header.chunkLength = input.readInt32();
+  header.flags = input.read();
+  LOGDEBUG(
+      "TcrConnection::readChunkHeader: "
+      ", chunkLen=%" PRId32 ", lastChunkAndSecurityFlags=0x%" PRIx8,
+      header.chunkLength, header.flags);
+
+  return header;
+}
+
+std::vector<uint8_t> TcrConnection::readChunkBody(
+    std::chrono::microseconds timeout, int32_t chunkLength) {
+  std::vector<uint8_t> chunkBody(chunkLength);
+  auto error = receiveData(reinterpret_cast<char*>(chunkBody.data()),
+                           chunkLength, timeout, true, false);
+  if (error != CONN_NOERR) {
+    if (error & CONN_TIMEOUT) {
+      throwException(
+          TimeoutException("TcrConnection::readChunkBody: "
+                           "connection timed out while receiving chunk body"));
+    } else {
+      throwException(
+          GeodeIOException("TcrConnection::readChunkBody: "
+                           "connection failure while receiving chunk body"));
+    }
+  }
+
+  LOGDEBUG(
+      "TcrConnection::readChunkBody: received chunk body from endpoint "
+      "%s; bytes: %s",
+      m_endpoint,
+      Utils::convertBytesToString(chunkBody.data(), chunkLength).c_str());
+  return chunkBody;
+}
+
+bool TcrConnection::processChunk(TcrMessageReply& reply,
+                                 std::chrono::microseconds timeout,
+                                 int32_t chunkLength,
+                                 int8_t lastChunkAndSecurityFlags) {
+  // NOTE: this buffer is allocated by readChunkBody, and reply.processChunk
+  // takes ownership, so we don't delete it here on failure
+  std::vector<uint8_t> chunkBody = readChunkBody(timeout, chunkLength);
+
+  // Process the chunk; the actual processing is done by a separate thread
+  // ThinClientBaseDM::m_chunkProcessor.
+  reply.processChunk(chunkBody, chunkLength,
+                     m_endpointObj->getDistributedMemberID(),
+                     lastChunkAndSecurityFlags);
+  // Return boolean indicating whether or not there are more chunks, i.e.
+  // the *inverse* of the flag indicating this is the last chunk.  It's a
+  // little confusing here, but makes calling code clearer.
+  return (lastChunkAndSecurityFlags & LAST_CHUNK_MASK) ? false : true;
+}
+
 void TcrConnection::close() {
   TcrMessage* closeMsg = TcrMessage::getCloseConnMessage(
       m_poolDM->getConnectionManager().getCacheImpl());
diff --git a/cppcache/src/TcrConnection.hpp b/cppcache/src/TcrConnection.hpp
index cd5bb21..fe18794 100644
--- a/cppcache/src/TcrConnection.hpp
+++ b/cppcache/src/TcrConnection.hpp
@@ -66,6 +66,18 @@
 namespace geode {
 namespace client {
 
+struct chunkHeader {
+  int32_t chunkLength;
+  int8_t flags;
+};
+
+struct chunkedResponseHeader {
+  int32_t messageType;
+  int32_t numberOfParts;
+  int32_t transactionId;
+  chunkHeader header;
+};
+
 enum ConnErrType {
   CONN_NOERR = 0x0,
   CONN_NODATA = 0x1,
@@ -113,7 +125,7 @@
    * @param     ports     List of local ports for connections to endpoint
    * @param     numPorts  Size of ports list
    */
-  bool InitTcrConnection(
+  bool initTcrConnection(
       TcrEndpoint* endpointObj, const char* endpoint,
       synchronized_set<std::unordered_set<uint16_t>>& ports,
       bool isClientNotification = false, bool isSecondary = false,
@@ -247,13 +259,13 @@
    * connection and sets the reply message
    * parameter.
    * @param      reply response message
-   * @param      receiveTimeoutSec read timeout in sec
+   * @param      receiveTimeout read timeout
    * @param      doHeaderTimeoutRetries retry when header receive times out
    * @exception  GeodeIOException  if an I/O error occurs (socket failure).
    * @exception  TimeoutException  if timeout happens during read
    */
   void readMessageChunked(TcrMessageReply& reply,
-                          std::chrono::microseconds receiveTimeoutSec,
+                          std::chrono::microseconds receiveTimeout,
                           bool doHeaderTimeoutRetries);
 
   /**
@@ -318,6 +330,20 @@
   int64_t connectionId;
   const TcrConnectionManager* m_connectionManager;
   DiffieHellman* m_dh;
+
+  std::chrono::microseconds calculateHeaderTimeout(
+      std::chrono::microseconds receiveTimeout, bool retry);
+
+  chunkedResponseHeader readResponseHeader(std::chrono::microseconds timeout);
+
+  chunkHeader readChunkHeader(std::chrono::microseconds timeout);
+
+  std::vector<uint8_t> readChunkBody(std::chrono::microseconds timeout,
+                                     int32_t chunkLength);
+
+  bool processChunk(TcrMessageReply& reply, std::chrono::microseconds timeout,
+                    int32_t chunkLength, int8_t lastChunkAndSecurityFlags);
+
   /**
    * To read Intantiator message(which meant for java client), here we are
    * ignoring it
@@ -417,6 +443,11 @@
   volatile bool m_isBeingUsed;
   std::atomic<uint32_t> m_isUsed;
   ThinClientPoolDM* m_poolDM;
+  bool useReplyTimeout(const TcrMessage& request) const;
+  std::chrono::microseconds sendWithTimeouts(
+      const char* data, size_t len, std::chrono::microseconds sendTimeout,
+      std::chrono::microseconds receiveTimeout);
+  bool replyHasResult(const TcrMessage& request, TcrMessageReply& reply);
 };
 }  // namespace client
 }  // namespace geode
diff --git a/cppcache/src/TcrConnectionManager.cpp b/cppcache/src/TcrConnectionManager.cpp
index 0a862ff..609c761 100644
--- a/cppcache/src/TcrConnectionManager.cpp
+++ b/cppcache/src/TcrConnectionManager.cpp
@@ -389,7 +389,6 @@
   }
   // Postconditions:
   // 1. endpointsList.size() > 0
-  GF_DEV_ASSERT(endpointsList.size() > 0);
 }
 
 void TcrConnectionManager::removeHAEndpoints() {
@@ -474,7 +473,6 @@
   LOGFINE("TcrConnectionManager: ending cleanup thread");
   //  Postcondition - all notification channels should be cleaned up by the end
   //  of this function.
-  GF_DEV_ASSERT(m_receiverReleaseList.size() == 0);
 }
 
 void TcrConnectionManager::cleanNotificationLists() {
diff --git a/cppcache/src/TcrDistributionManager.cpp b/cppcache/src/TcrDistributionManager.cpp
index da4c0ac..6b7aa8d 100644
--- a/cppcache/src/TcrDistributionManager.cpp
+++ b/cppcache/src/TcrDistributionManager.cpp
@@ -16,6 +16,8 @@
  */
 #include "TcrDistributionManager.hpp"
 
+#include <cassert>
+
 #include <geode/ExceptionTypes.hpp>
 #include <geode/internal/geode_globals.hpp>
 
@@ -29,7 +31,7 @@
 TcrDistributionManager::TcrDistributionManager(
     ThinClientRegion* region, TcrConnectionManager& connManager)
     : ThinClientDistributionManager(connManager, region) {
-  GF_R_ASSERT(region != nullptr);
+  assert(region != nullptr);
   m_clientNotification = region->getAttributes().getClientNotificationEnabled();
 }
 
diff --git a/cppcache/src/TcrEndpoint.cpp b/cppcache/src/TcrEndpoint.cpp
index 7b57e5d..5ef3e0e 100644
--- a/cppcache/src/TcrEndpoint.cpp
+++ b/cppcache/src/TcrEndpoint.cpp
@@ -95,8 +95,6 @@
           "to subscription channel while closing",
           m_name.c_str());
       // fail in dev build to track #295 better in regressions
-      GF_DEV_ASSERT(m_numRegionListener == 0);
-
       m_numRegionListener = 0;
       closeNotification();
     }
@@ -150,7 +148,7 @@
         LOGFINE("TcrEndpoint::createNewConnectionWL got lock");
         newConn =
             new TcrConnection(m_cacheImpl->tcrConnectionManager(), m_connected);
-        newConn->InitTcrConnection(this, m_name.c_str(), m_ports,
+        newConn->initTcrConnection(this, m_name.c_str(), m_ports,
                                    isClientNotification, isSecondary,
                                    connectTimeout);
 
@@ -185,7 +183,7 @@
 GfErrType TcrEndpoint::createNewConnection(
     TcrConnection*& newConn, bool isClientNotification, bool isSecondary,
     std::chrono::microseconds connectTimeout, int32_t timeoutRetries,
-    bool sendUpdateNotification, bool appThreadRequest) {
+    bool appThreadRequest) {
   LOGFINE(
       "TcrEndpoint::createNewConnection: connectTimeout =%d "
       "m_needToConnectInLock=%d appThreadRequest =%d",
@@ -198,7 +196,7 @@
         if (!needtoTakeConnectLock() || !appThreadRequest) {
           newConn = new TcrConnection(m_cacheImpl->tcrConnectionManager(),
                                       m_connected);
-          bool authenticate = newConn->InitTcrConnection(
+          bool authenticate = newConn->initTcrConnection(
               this, m_name.c_str(), m_ports, isClientNotification, isSecondary,
               connectTimeout);
           if (authenticate) {
@@ -214,30 +212,11 @@
         }
         // m_connected = true;
       }
-      if (!isClientNotification && sendUpdateNotification) {
-        bool notificationStarted;
-        {
-          std::lock_guard<decltype(m_notifyReceiverLock)> guard(
-              m_notifyReceiverLock);
-          notificationStarted = (m_numRegionListener > 0) || m_isQueueHosted;
-        }
-        if (notificationStarted) {
-          LOGFINE("Sending update notification message to endpoint %s",
-                  m_name.c_str());
-          TcrMessageUpdateClientNotification updateNotificationMsg(
-              new DataOutput(newConn->getConnectionManager()
-                                 .getCacheImpl()
-                                 ->createDataOutput()),
-              static_cast<int32_t>(newConn->getPort()));
-          newConn->send(updateNotificationMsg.getMsgData(),
-                        updateNotificationMsg.getMsgLength());
-        }
-      }
       err = GF_NOERR;
       break;
     } catch (const TimeoutException&) {
       LOGINFO("Timeout in handshake with endpoint[%s]", m_name.c_str());
-      err = GF_TIMOUT;
+      err = GF_TIMEOUT;
       m_needToConnectInLock = true;  // while creating the connection
       std::this_thread::sleep_for(std::chrono::milliseconds(50));
     } catch (const GeodeIOException& ex) {
@@ -286,10 +265,10 @@
 void TcrEndpoint::authenticateEndpoint(TcrConnection*& conn) {
   LOGDEBUG(
       "TcrEndpoint::authenticateEndpoint m_isAuthenticated  = %d "
-      "this->m_baseDM = %d",
-      m_isAuthenticated, m_baseDM);
+      "m_baseDM = %d, connection = %p",
+      m_isAuthenticated, m_baseDM, conn);
   if (!m_isAuthenticated && m_baseDM) {
-    this->setConnected();
+    setConnected();
     std::lock_guard<decltype(m_endpointAuthenticationLock)> guard(
         m_endpointAuthenticationLock);
     GfErrType err = GF_NOERR;
@@ -306,11 +285,14 @@
         new DataOutput(m_cacheImpl->createDataOutput()), creds, m_baseDM);
 
     LOGDEBUG("request is created");
-    TcrMessageReply reply(true, this->m_baseDM);
-    // err = this->sendRequestToEP(request, reply, ( *it ).int_id_);
-    err = this->sendRequestConnWithRetry(request, reply, conn);
-    LOGDEBUG("authenticateEndpoint error = %d", err);
+    TcrMessageReply reply(true, m_baseDM);
+    err = sendRequestConnWithRetry(request, reply, conn);
+    LOGDEBUG("TcrEndpoint::authenticateEndpoint - ERROR: %d", err);
     if (err == GF_NOERR) {
+      LOGDEBUG(
+          "TcrEndpoint::authenticateEndpoint - successfully authenticated on "
+          "conn %p",
+          conn);
       // put the object into local region
       switch (reply.getMessageType()) {
         case TcrMessage::RESPONSE: {
@@ -331,7 +313,7 @@
       }
     }
     // throw exception if it is not authenticated
-    GfErrTypeToException("TcrEndpoint::authenticateEndpoint", err);
+    throwExceptionIfError("TcrEndpoint::authenticateEndpoint", err);
 
     m_isAuthenticated = true;
   }
@@ -391,7 +373,6 @@
                                   ThinClientBaseDM* distMgr) {
   // Pre-conditions:
   // 1. If this is a secondary server then clientNotification must be true
-  GF_DEV_ASSERT(!isSecondary || clientNotification);
 
   bool connected = false;
   GfErrType err = GF_NOERR;
@@ -491,20 +472,6 @@
   // 1. The endpoint should be marked as active, only if m_connected is true
   // 2. If this is not an active endpoint and it is connected then only one
   //    connection + notify channel
-  GF_DEV_ASSERT(!m_isActiveEndpoint || m_connected);
-#if GF_DEVEL_ASSERTS == 1
-  int numConnections = m_opConnections.size();
-  if (!m_isActiveEndpoint && !isActiveEndpoint && m_connected &&
-      (numConnections != 1 || m_numRegionListener <= 0 ||
-       m_notifyReceiver == nullptr)) {
-    LOGWARN(
-        "Inactive connected endpoint does not have exactly one "
-        "connection. Number of connections: %d, number of region listeners: "
-        "%d",
-        numConnections, m_numRegionListener);
-  }
-#endif
-
   return err;
 }
 
@@ -552,7 +519,7 @@
     if (error == GF_NOERR) {
       m_pingSent = true;
     }
-    if (error == GF_TIMOUT && m_pingTimeouts < 2) {
+    if (error == GF_TIMEOUT && m_pingTimeouts < 2) {
       ++m_pingTimeouts;
     } else {
       m_pingTimeouts = 0;
@@ -612,7 +579,7 @@
         msg = new TcrMessageReply(true, m_baseDM);
         msg->initCqMap();
         msg->setData(data, static_cast<int32_t>(dataLen),
-                     this->getDistributedMemberID(),
+                     getDistributedMemberID(),
                      *(m_cacheImpl->getSerializationRegistry()),
                      *(m_cacheImpl->getMemberListForVersionStamp()));
         handleNotificationStats(static_cast<int64_t>(dataLen));
@@ -793,7 +760,9 @@
   if (((type == TcrMessage::EXECUTE_FUNCTION ||
         type == TcrMessage::EXECUTE_REGION_FUNCTION) &&
        (request.hasResult() & 2))) {
-    sendRequestForChunkedResponse(request, reply, conn);
+    conn->sendRequestForChunkedResponse(request, request.getMsgLength(), reply,
+                                        request.getTimeout(),
+                                        reply.getTimeout());
   } else if (type == TcrMessage::REGISTER_INTEREST_LIST ||
              type == TcrMessage::REGISTER_INTEREST ||
              type == TcrMessage::QUERY ||
@@ -824,7 +793,9 @@
              type == TcrMessage::MONITORCQ_MSG_TYPE ||
              type == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE ||
              type == TcrMessage::GETDURABLECQS_MSG_TYPE) {
-    sendRequestForChunkedResponse(request, reply, conn);
+    conn->sendRequestForChunkedResponse(request, request.getMsgLength(), reply,
+                                        request.getTimeout(),
+                                        reply.getTimeout());
     LOGDEBUG("sendRequestConn: calling sendRequestForChunkedResponse DONE");
   } else {
     // Chk request type to request if so request.getCallBackArg flag & setCall
@@ -841,7 +812,7 @@
                                   reply.getTimeout(), request.getMessageType());
     reply.setMessageTypeRequest(type);
     reply.setData(
-        data, static_cast<int32_t>(dataLen), this->getDistributedMemberID(),
+        data, static_cast<int32_t>(dataLen), getDistributedMemberID(),
         *(m_cacheImpl->getSerializationRegistry()),
         *(m_cacheImpl
               ->getMemberListForVersionStamp()));  // memory is released by
@@ -985,7 +956,7 @@
           return GF_NOERR;
         }
       } catch (const TimeoutException&) {
-        error = GF_TIMOUT;
+        error = GF_TIMEOUT;
         LOGFINE(
             "Send timed out for endpoint %s. "
             "Message txid = %d",
@@ -1072,7 +1043,7 @@
         epFailure = true;
         failReason = "server connection could not be obtained";
         if (timeout <= std::chrono::microseconds::zero()) {
-          error = GF_TIMOUT;
+          error = GF_TIMEOUT;
           LOGWARN(
               "No connection available for %ld seconds "
               "for endpoint %s.",
@@ -1086,8 +1057,6 @@
         }
       } else {
         LOGERROR("Unexpected failure while sending request to server.");
-        GF_DEV_ASSERT("Bug in TcrEndpoint::sendRequestWithRetry()?" ? false
-                                                                    : true);
       }
     }
   } while (++sendRetryCount <= maxSendRetries);
@@ -1129,17 +1098,6 @@
     setConnectionStatus(false);
   }
 
-// Postconditions:
-#if GF_DEVEL_ASSERTS == 1
-  int opConnectionsSize = m_opConnections.size();
-  if (!m_isActiveEndpoint && (opConnectionsSize > 1)) {
-    LOGWARN("Connections size = %d, expected maximum %d", opConnectionsSize, 1);
-  } else if (opConnectionsSize > m_maxConnections) {
-    LOGWARN("Connections size = %d, expected maximum %d", opConnectionsSize,
-            m_maxConnections);
-  }
-#endif
-
   return error;
 }
 
@@ -1313,12 +1271,6 @@
   return m_cacheImpl->getQueryService(true);
 }
 
-void TcrEndpoint::sendRequestForChunkedResponse(const TcrMessage& request,
-                                                TcrMessageReply& reply,
-                                                TcrConnection* conn) {
-  conn->sendRequestForChunkedResponse(request, request.getMsgLength(), reply);
-}
-
 void TcrEndpoint::closeFailedConnection(TcrConnection*& conn) {
   closeConnection(conn);
 }
diff --git a/cppcache/src/TcrEndpoint.hpp b/cppcache/src/TcrEndpoint.hpp
index 4413529..e80ca33 100644
--- a/cppcache/src/TcrEndpoint.hpp
+++ b/cppcache/src/TcrEndpoint.hpp
@@ -157,8 +157,7 @@
       TcrConnection*& newConn, bool isClientNotification = false,
       bool isSecondary = false,
       std::chrono::microseconds connectTimeout = DEFAULT_CONNECT_TIMEOUT,
-      int32_t timeoutRetries = 1, bool sendUpdateNotification = true,
-      bool appThreadRequest = false);
+      int32_t timeoutRetries = 1, bool appThreadRequest = false);
 
   bool needtoTakeConnectLock();
 
@@ -210,9 +209,6 @@
   virtual void processMarker();
   virtual void triggerRedundancyThread();
   virtual std::shared_ptr<QueryService> getQueryService();
-  virtual void sendRequestForChunkedResponse(const TcrMessage& request,
-                                             TcrMessageReply& reply,
-                                             TcrConnection* conn);
   virtual void closeFailedConnection(TcrConnection*& conn);
   void closeConnection(TcrConnection*& conn);
   virtual void handleNotificationStats(int64_t byteLength);
diff --git a/cppcache/src/TcrHADistributionManager.cpp b/cppcache/src/TcrHADistributionManager.cpp
index af0529e..fac5ef0 100644
--- a/cppcache/src/TcrHADistributionManager.cpp
+++ b/cppcache/src/TcrHADistributionManager.cpp
@@ -17,6 +17,8 @@
 
 #include "TcrHADistributionManager.hpp"
 
+#include <cassert>
+
 #include <geode/ExceptionTypes.hpp>
 #include <geode/internal/geode_globals.hpp>
 
@@ -36,7 +38,7 @@
     ThinClientRegion* theRegion, TcrConnectionManager& connManager)
     : ThinClientDistributionManager(connManager, theRegion),
       m_theTcrConnManager(connManager) {
-  GF_R_ASSERT(theRegion != nullptr);
+  assert(theRegion != nullptr);
 }
 
 void TcrHADistributionManager::init() {
diff --git a/cppcache/src/TcrMessage.cpp b/cppcache/src/TcrMessage.cpp
index e5b6f93..f1a51fe 100644
--- a/cppcache/src/TcrMessage.cpp
+++ b/cppcache/src/TcrMessage.cpp
@@ -23,7 +23,6 @@
 #include <geode/CacheableObjectArray.hpp>
 #include <geode/SystemProperties.hpp>
 
-#include "Assert.hpp"
 #include "AutoDelete.hpp"
 #include "CacheRegionHelper.hpp"
 #include "DataInputInternal.hpp"
@@ -47,20 +46,299 @@
 namespace apache {
 namespace geode {
 namespace client {
-static const uint32_t REGULAR_EXPRESSION =
+namespace {
+const uint32_t g_headerLen = 17;
+const uint32_t REGULAR_EXPRESSION =
     1;  // come from Java InterestType.REGULAR_EXPRESSION
 
-namespace {
-uint32_t g_headerLen = 17;
+inline void readInt(uint8_t* buffer, uint16_t* value) {
+  uint16_t tmp = *(buffer++);
+  tmp = (tmp << 8) | *(buffer);
+  *value = tmp;
+}
+
+inline void readInt(uint8_t* buffer, uint32_t* value) {
+  uint32_t tmp = *(buffer++);
+  tmp = (tmp << 8) | *(buffer++);
+  tmp = (tmp << 8) | *(buffer++);
+  tmp = (tmp << 8) | *(buffer++);
+  *value = tmp;
+}
+
+inline void writeInt(uint8_t* buffer, uint16_t value) {
+  *(buffer++) = static_cast<uint8_t>(value >> 8);
+  *(buffer++) = static_cast<uint8_t>(value);
+}
+
+inline void writeInt(uint8_t* buffer, uint32_t value) {
+  *(buffer++) = static_cast<uint8_t>(value >> 24);
+  *(buffer++) = static_cast<uint8_t>(value >> 16);
+  *(buffer++) = static_cast<uint8_t>(value >> 8);
+  *(buffer++) = static_cast<uint8_t>(value);
+}
 }  // namespace
 
 extern void setThreadLocalExceptionMessage(const char*);
 
 // AtomicInc TcrMessage::m_transactionId = 0;
-uint8_t* TcrMessage::m_keepalive = nullptr;
+uint8_t* TcrMessage::m_keepAlive = nullptr;
 const int TcrMessage::m_flag_empty = 0x01;
 const int TcrMessage::m_flag_concurrency_checks = 0x02;
 
+bool TcrMessage::isKeepAlive() { return (m_keepAlive && (*m_keepAlive > 0)); }
+
+bool TcrMessage::isUserInitiativeOps(const TcrMessage& msg) {
+  int32_t msgType = msg.getMessageType();
+
+  if (!msg.isMetaRegion() &&
+      !(msgType == TcrMessage::PING || msgType == TcrMessage::PERIODIC_ACK ||
+        msgType == TcrMessage::MAKE_PRIMARY ||
+        msgType == TcrMessage::CLOSE_CONNECTION ||
+        msgType == TcrMessage::CLIENT_READY || msgType == TcrMessage::INVALID ||
+        msgType == TcrMessage::MONITORCQ_MSG_TYPE ||
+        msgType == TcrMessage::GETCQSTATS_MSG_TYPE ||
+        msgType == TcrMessage::REQUEST_EVENT_VALUE ||
+        msgType == TcrMessage::GET_CLIENT_PR_METADATA ||
+        msgType == TcrMessage::GET_CLIENT_PARTITION_ATTRIBUTES ||
+        msgType == TcrMessage::GET_PDX_ID_FOR_TYPE ||
+        msgType == TcrMessage::GET_PDX_TYPE_BY_ID ||
+        msgType == TcrMessage::ADD_PDX_TYPE || msgType == TcrMessage::SIZE ||
+        msgType == TcrMessage::TX_FAILOVER ||
+        msgType == TcrMessage::GET_ENTRY ||
+        msgType == TcrMessage::TX_SYNCHRONIZATION ||
+        msgType == TcrMessage::GET_FUNCTION_ATTRIBUTES ||
+        msgType == TcrMessage::ADD_PDX_ENUM ||
+        msgType == TcrMessage::GET_PDX_ENUM_BY_ID ||
+        msgType == TcrMessage::GET_PDX_ID_FOR_ENUM ||
+        msgType == TcrMessage::COMMIT || msgType == TcrMessage::ROLLBACK)) {
+    return true;
+  }
+  return false;
+}
+
+TcrMessage::TcrMessage()
+    : m_request(nullptr),
+      m_tcdm(nullptr),
+      m_chunkedResult(nullptr),
+      m_keyList(nullptr),
+      m_region(nullptr),
+      m_timeout(15 /*DEFAULT_TIMEOUT_SECONDS*/),
+      m_metadata(),
+      m_cqs(nullptr),
+      m_messageResponseTimeout(-1),
+      m_delta(nullptr),
+      m_deltaBytes(nullptr),
+      m_fpaSet(),
+      m_functionAttributes(),
+      m_connectionIDBytes(nullptr),
+      m_creds(),
+      m_key(),
+      m_value(nullptr),
+      m_failedNode(),
+      m_callbackArgument(nullptr),
+      m_versionTag(),
+      m_eventid(nullptr),
+      m_vectorPtr(),
+      m_bucketServerLocation(nullptr),
+      m_tombstoneVersions(),
+      m_tombstoneKeys(),
+      m_versionObjPartListptr(),
+      exceptionMessage(),
+      m_regionName("INVALID_REGION_NAME"),
+      m_regex(),
+      m_bucketServerLocations(),
+      m_colocatedWith(),
+      m_partitionResolverName(),
+      m_securityHeaderLength(0),
+      m_msgType(TcrMessage::INVALID),
+      m_msgLength(-1),
+      m_msgTypeRequest(0),
+      m_txId(-1),
+      m_bucketCount(0),
+      m_numCqPart(0),
+      m_msgTypeForCq(0),
+      m_deltaBytesLen(0),
+      m_entryNotFound(0),
+      m_feAnotherHop(false),
+      isSecurityOn(false),
+      m_isLastChunkAndisSecurityHeader(0),
+      m_isSecurityHeaderAdded(false),
+      m_isMetaRegion(false),
+      m_decodeAll(false),
+      m_interestPolicy(0),
+      m_isDurable(false),
+      m_receiveValues(false),
+      m_hasCqsPart(false),
+      m_isInterestListPassed(false),
+      m_shouldIgnore(false),
+      m_metaDataVersion(0),
+      m_serverGroupVersion(0),
+      m_boolValue(0),
+      m_isCallBackArguement(false),
+      m_hasResult(0) {}
+
+const std::vector<std::shared_ptr<CacheableKey>>* TcrMessage::getKeys() const {
+  return m_keyList;
+}
+
+const std::string& TcrMessage::getRegex() const { return m_regex; }
+
+InterestResultPolicy TcrMessage::getInterestResultPolicy() const {
+  if (m_interestPolicy == 2) {
+    return InterestResultPolicy::KEYS_VALUES;
+  } else if (m_interestPolicy == 1) {
+    return InterestResultPolicy::KEYS;
+  } else {
+    return InterestResultPolicy::NONE;
+  }
+}
+
+bool TcrMessage::forPrimary() const {
+  return m_msgType == TcrMessage::PUT || m_msgType == TcrMessage::DESTROY ||
+         m_msgType == TcrMessage::EXECUTE_REGION_FUNCTION;
+}
+
+void TcrMessage::initCqMap() { m_cqs = new std::map<std::string, int>(); }
+
+bool TcrMessage::forSingleHop() const {
+  return m_msgType == TcrMessage::PUT || m_msgType == TcrMessage::DESTROY ||
+         m_msgType == TcrMessage::REQUEST ||
+         m_msgType == TcrMessage::GET_ALL_70 ||
+         m_msgType == TcrMessage::GET_ALL_WITH_CALLBACK ||
+         m_msgType == TcrMessage::EXECUTE_REGION_FUNCTION ||
+         m_msgType == TcrMessage::PUTALL ||
+         m_msgType == TcrMessage::PUT_ALL_WITH_CALLBACK;
+}
+
+bool TcrMessage::forTransaction() const { return m_txId != -1; }
+
+bool TcrMessage::getBoolValue() const { return m_boolValue; }
+
+const char* TcrMessage::getException() {
+  exceptionMessage = Utils::nullSafeToString(m_value);
+  return exceptionMessage.c_str();
+}
+
+bool TcrMessage::isDurable() const { return m_isDurable; }
+
+bool TcrMessage::receiveValues() const { return m_receiveValues; }
+
+bool TcrMessage::hasCqPart() const { return m_hasCqsPart; }
+
+uint32_t TcrMessage::getMessageTypeForCq() const { return m_msgTypeForCq; }
+
+bool TcrMessage::isInterestListPassed() const { return m_isInterestListPassed; }
+
+bool TcrMessage::shouldIgnore() const { return m_shouldIgnore; }
+
+int8_t TcrMessage::getMetaDataVersion() const { return m_metaDataVersion; }
+
+uint32_t TcrMessage::getEntryNotFound() const { return m_entryNotFound; }
+
+int8_t TcrMessage::getserverGroupVersion() const {
+  return m_serverGroupVersion;
+}
+
+std::vector<int8_t>* TcrMessage::getFunctionAttributes() {
+  return m_functionAttributes;
+}
+
+void TcrMessage::setDM(ThinClientBaseDM* dm) { m_tcdm = dm; }
+
+ThinClientBaseDM* TcrMessage::getDM() { return m_tcdm; }
+
+// set the chunked response handler
+void TcrMessage::setChunkedResultHandler(TcrChunkedResult* chunkedResult) {
+  m_isLastChunkAndisSecurityHeader = 0x0;
+  m_chunkedResult = chunkedResult;
+}
+
+TcrChunkedResult* TcrMessage::getChunkedResultHandler() {
+  return m_chunkedResult;
+}
+
+void TcrMessage::setVersionedObjectPartList(
+    std::shared_ptr<VersionedCacheableObjectPartList> versionObjPartListptr) {
+  m_versionObjPartListptr = versionObjPartListptr;
+}
+
+std::shared_ptr<VersionedCacheableObjectPartList>
+TcrMessage::getVersionedObjectPartList() {
+  return m_versionObjPartListptr;
+}
+
+DataInput* TcrMessage::getDelta() { return m_delta.get(); }
+
+//  getDeltaBytes( ) is called *only* by CqService, returns a CacheableBytes
+//  that
+// takes ownership of delta bytes.
+std::shared_ptr<CacheableBytes> TcrMessage::getDeltaBytes() {
+  if (m_deltaBytes == nullptr) {
+    return nullptr;
+  }
+  auto retVal = CacheableBytes::create(
+      std::vector<int8_t>(m_deltaBytes, m_deltaBytes + m_deltaBytesLen));
+  m_deltaBytes = nullptr;
+  return retVal;
+}
+
+bool TcrMessage::hasDelta() { return (m_delta != nullptr); }
+
+void TcrMessage::setMetaRegion(bool isMetaRegion) {
+  m_isMetaRegion = isMetaRegion;
+}
+
+bool TcrMessage::isMetaRegion() const { return m_isMetaRegion; }
+
+int32_t TcrMessage::getNumBuckets() const { return m_bucketCount; }
+
+const std::string& TcrMessage::getColocatedWith() const {
+  return m_colocatedWith;
+}
+
+const std::string& TcrMessage::getPartitionResolver() const {
+  return m_partitionResolverName;
+}
+
+std::vector<std::vector<std::shared_ptr<BucketServerLocation>>>*
+TcrMessage::getMetadata() {
+  return m_metadata;
+}
+
+std::vector<std::shared_ptr<FixedPartitionAttributesImpl>>*
+TcrMessage::getFpaSet() {
+  return m_fpaSet;
+}
+
+std::shared_ptr<CacheableHashSet> TcrMessage::getFailedNode() {
+  return m_failedNode;
+}
+
+bool TcrMessage::isCallBackArguement() const { return m_isCallBackArguement; }
+
+void TcrMessage::setCallBackArguement(bool aCallBackArguement) {
+  m_isCallBackArguement = aCallBackArguement;
+}
+
+void TcrMessage::setBucketServerLocation(
+    std::shared_ptr<BucketServerLocation> serverLocation) {
+  m_bucketServerLocation = serverLocation;
+}
+void TcrMessage::setVersionTag(std::shared_ptr<VersionTag> versionTag) {
+  m_versionTag = versionTag;
+}
+std::shared_ptr<VersionTag> TcrMessage::getVersionTag() { return m_versionTag; }
+
+uint8_t TcrMessage::hasResult() const { return m_hasResult; }
+
+std::shared_ptr<CacheableHashMap> TcrMessage::getTombstoneVersions() const {
+  return m_tombstoneVersions;
+}
+
+std::shared_ptr<CacheableHashSet> TcrMessage::getTombstoneKeys() const {
+  return m_tombstoneKeys;
+}
+
 TcrMessagePing* TcrMessage::getPingMessage(CacheImpl* cacheImpl) {
   static auto pingMsg =
       new TcrMessagePing(new DataOutput(cacheImpl->createDataOutput()), true);
@@ -80,8 +358,8 @@
 
 void TcrMessage::setKeepAlive(bool keepalive) {
   // TODO global
-  if (TcrMessage::m_keepalive != nullptr) {
-    *TcrMessage::m_keepalive = keepalive ? 1 : 0;
+  if (TcrMessage::m_keepAlive != nullptr) {
+    *TcrMessage::m_keepAlive = keepalive ? 1 : 0;
   }
 }
 
@@ -227,8 +505,7 @@
   }
 }
 
-inline void TcrMessage::readCallbackObjectPart(DataInput& input,
-                                               bool defaultString) {
+void TcrMessage::readCallbackObjectPart(DataInput& input, bool defaultString) {
   int32_t lenObj = input.readInt32();
   const auto isObj = input.readBoolean();
   if (lenObj > 0) {
@@ -244,7 +521,7 @@
   }
 }
 
-inline void TcrMessage::readObjectPart(DataInput& input, bool defaultString) {
+void TcrMessage::readObjectPart(DataInput& input, bool defaultString) {
   int32_t lenObj = input.readInt32();
   auto isObj = input.read();
   if (lenObj > 0) {
@@ -353,7 +630,7 @@
   return 0;
 }
 
-inline void TcrMessage::readFailedNodePart(DataInput& input) {
+void TcrMessage::readFailedNodePart(DataInput& input) {
   // read and ignore length
   input.readInt32();
   // read and ignore isObj
@@ -365,7 +642,7 @@
   LOGDEBUG("readFailedNodePart m_failedNode size = %d ", m_failedNode->size());
 }
 
-inline void TcrMessage::readKeyPart(DataInput& input) {
+void TcrMessage::readKeyPart(DataInput& input) {
   int32_t lenObj = input.readInt32();
   const auto isObj = input.readBoolean();
   if (lenObj > 0) {
@@ -378,17 +655,6 @@
   }
 }
 
-inline void TcrMessage::writeInt(uint8_t* buffer, uint16_t value) {
-  *(buffer++) = static_cast<uint8_t>(value >> 8);
-  *(buffer++) = static_cast<uint8_t>(value);
-}
-
-inline void TcrMessage::writeInt(uint8_t* buffer, uint32_t value) {
-  *(buffer++) = static_cast<uint8_t>(value >> 24);
-  *(buffer++) = static_cast<uint8_t>(value >> 16);
-  *(buffer++) = static_cast<uint8_t>(value >> 8);
-  *(buffer++) = static_cast<uint8_t>(value);
-}
 std::shared_ptr<Serializable> TcrMessage::readCacheableString(DataInput& input,
                                                               int lenObj) {
   auto decoded = internal::JavaModifiedUtf8::decode(
@@ -515,20 +781,6 @@
   m_request->advanceCursor(sizeOfSerializedObj + 1);
 }
 
-void TcrMessage::readInt(uint8_t* buffer, uint16_t* value) {
-  uint16_t tmp = *(buffer++);
-  tmp = (tmp << 8) | *(buffer);
-  *value = tmp;
-}
-
-void TcrMessage::readInt(uint8_t* buffer, uint32_t* value) {
-  uint32_t tmp = *(buffer++);
-  tmp = (tmp << 8) | *(buffer++);
-  tmp = (tmp << 8) | *(buffer++);
-  tmp = (tmp << 8) | *(buffer++);
-  *value = tmp;
-}
-
 void TcrMessage::writeBytesOnly(const std::shared_ptr<Serializable>& se) {
   auto cBufferLength = m_request->getBufferLength();
   uint8_t* startBytes = nullptr;
@@ -714,7 +966,7 @@
   }
 }
 
-void TcrMessage::processChunk(const uint8_t* bytes, int32_t len,
+void TcrMessage::processChunk(const std::vector<uint8_t>& chunk, int32_t len,
                               uint16_t endpointmemId,
                               const uint8_t isLastChunkAndisSecurityHeader) {
   // TODO: see if security header is there
@@ -733,7 +985,7 @@
   switch (m_msgType) {
     case TcrMessage::REPLY: {
       LOGDEBUG("processChunk - got reply for request %d", m_msgTypeRequest);
-      chunkSecurityHeader(1, bytes, len, isLastChunkAndisSecurityHeader);
+      chunkSecurityHeader(1, chunk, len, isLastChunkAndisSecurityHeader);
       break;
     }
     case TcrMessage::RESPONSE: {
@@ -749,12 +1001,12 @@
         break;
       } else if (m_msgTypeRequest == TcrMessage::PUTALL ||
                  m_msgTypeRequest == TcrMessage::PUT_ALL_WITH_CALLBACK) {
-        TcrChunkedContext* chunk = new TcrChunkedContext(
-            bytes, len, m_chunkedResult, isLastChunkAndisSecurityHeader,
+        TcrChunkedContext* chunkedContext = new TcrChunkedContext(
+            chunk, len, m_chunkedResult, isLastChunkAndisSecurityHeader,
             m_tcdm->getConnectionManager().getCacheImpl());
         m_chunkedResult->setEndpointMemId(endpointmemId);
-        m_tcdm->queueChunk(chunk);
-        if (bytes == nullptr) {
+        m_tcdm->queueChunk(chunkedContext);
+        if (chunk.empty()) {
           // last chunk -- wait for processing of all the chunks to complete
           m_chunkedResult->waitFinalize();
           auto ex = m_chunkedResult->getException();
@@ -773,12 +1025,12 @@
     case TcrMessage::RESPONSE_FROM_PRIMARY: {
       if (m_chunkedResult != nullptr) {
         LOGDEBUG("tcrmessage in case22 ");
-        TcrChunkedContext* chunk = new TcrChunkedContext(
-            bytes, len, m_chunkedResult, isLastChunkAndisSecurityHeader,
+        TcrChunkedContext* chunkedContext = new TcrChunkedContext(
+            chunk, len, m_chunkedResult, isLastChunkAndisSecurityHeader,
             m_tcdm->getConnectionManager().getCacheImpl());
         m_chunkedResult->setEndpointMemId(endpointmemId);
-        m_tcdm->queueChunk(chunk);
-        if (bytes == nullptr) {
+        m_tcdm->queueChunk(chunkedContext);
+        if (chunk.empty()) {
           // last chunk -- wait for processing of all the chunks to complete
           m_chunkedResult->waitFinalize();
           //  Throw any exception during processing here.
@@ -796,9 +1048,8 @@
       } else if (TcrMessage::CQ_EXCEPTION_TYPE == m_msgType ||
                  TcrMessage::CQDATAERROR_MSG_TYPE == m_msgType ||
                  TcrMessage::GET_ALL_DATA_ERROR == m_msgType) {
-        if (bytes != nullptr) {
-          chunkSecurityHeader(1, bytes, len, isLastChunkAndisSecurityHeader);
-          _GEODE_SAFE_DELETE_ARRAY(bytes);
+        if (!chunk.empty()) {
+          chunkSecurityHeader(1, chunk, len, isLastChunkAndisSecurityHeader);
         }
       }
       break;
@@ -807,7 +1058,7 @@
                                                     // error
     case EXECUTE_FUNCTION_ERROR:
     case EXECUTE_REGION_FUNCTION_ERROR: {
-      if (bytes != nullptr) {
+      if (!chunk.empty()) {
         // DeleteArray<const uint8_t> delChunk(bytes);
         //  DataInput input(bytes, len);
         // TODO: this not send two part...
@@ -815,17 +1066,15 @@
         // readExceptionPart(input, false);
         // readSecureObjectPart(input, false, true,
         // isLastChunkAndisSecurityHeader );
-        chunkSecurityHeader(1, bytes, len, isLastChunkAndisSecurityHeader);
-        _GEODE_SAFE_DELETE_ARRAY(bytes);
+        chunkSecurityHeader(1, chunk, len, isLastChunkAndisSecurityHeader);
       }
       break;
     }
     case TcrMessage::EXCEPTION: {
-      if (bytes != nullptr) {
-        DeleteArray<const uint8_t> delChunk(bytes);
+      if (!chunk.empty()) {
         auto input =
             m_tcdm->getConnectionManager().getCacheImpl()->createDataInput(
-                bytes, len);
+                chunk.data(), len);
         readExceptionPart(input, isLastChunkAndisSecurityHeader);
         readSecureObjectPart(input, false, true,
                              isLastChunkAndisSecurityHeader);
@@ -834,42 +1083,41 @@
     }
     case TcrMessage::RESPONSE_FROM_SECONDARY: {
       // TODO: how many parts
-      chunkSecurityHeader(1, bytes, len, isLastChunkAndisSecurityHeader);
-      if (bytes != nullptr) {
-        DeleteArray<const uint8_t> delChunk(bytes);
+      chunkSecurityHeader(1, chunk, len, isLastChunkAndisSecurityHeader);
+      if (chunk.size()) {
         LOGFINEST("processChunk - got response from secondary, ignoring.");
       }
       break;
     }
     case TcrMessage::PUT_DATA_ERROR: {
-      chunkSecurityHeader(1, bytes, len, isLastChunkAndisSecurityHeader);
-      if (nullptr != bytes) {
+      chunkSecurityHeader(1, chunk, len, isLastChunkAndisSecurityHeader);
+      if (!chunk.empty()) {
         auto input =
             m_tcdm->getConnectionManager().getCacheImpl()->createDataInput(
-                bytes, len);
+                chunk.data(), len);
         auto errorString = readStringPart(input);
 
         if (!errorString.empty()) {
+          errorString.erase(
+              errorString.begin(),
+              std::find_if(errorString.begin(), errorString.end(),
+                           std::not1(std::ptr_fun<int, int>(std::isspace))));
+          LOGDEBUG(
+              "TcrMessage::%s: setting thread-local ex msg to \"%s\", %s, %d",
+              __FUNCTION__, errorString.c_str(), __FILE__, __LINE__);
           setThreadLocalExceptionMessage(errorString.c_str());
         }
-
-        _GEODE_SAFE_DELETE_ARRAY(bytes);
       }
       break;
     }
     case TcrMessage::GET_ALL_DATA_ERROR: {
-      chunkSecurityHeader(1, bytes, len, isLastChunkAndisSecurityHeader);
-      if (bytes != nullptr) {
-        _GEODE_SAFE_DELETE_ARRAY(bytes);
-      }
+      chunkSecurityHeader(1, chunk, len, isLastChunkAndisSecurityHeader);
 
       break;
     }
     default: {
       // TODO: how many parts what should we do here
-      if (bytes != nullptr) {
-        _GEODE_SAFE_DELETE_ARRAY(bytes);
-      } else {
+      if (chunk.empty()) {
         LOGWARN(
             "Got unhandled message type %d while processing response, possible "
             "serialization mismatch",
@@ -890,13 +1138,14 @@
   return nullptr;
 }
 
-void TcrMessage::chunkSecurityHeader(int skipPart, const uint8_t* bytes,
+void TcrMessage::chunkSecurityHeader(int skipPart,
+                                     const std::vector<uint8_t> bytes,
                                      int32_t len,
                                      uint8_t isLastChunkAndSecurityHeader) {
   LOGDEBUG("TcrMessage::chunkSecurityHeader:: skipParts = %d", skipPart);
   if ((isLastChunkAndSecurityHeader & 0x3) == 0x3) {
     auto di = m_tcdm->getConnectionManager().getCacheImpl()->createDataInput(
-        bytes, len);
+        bytes.data(), len);
     skipParts(di, skipPart);
     readSecureObjectPart(di, false, true, isLastChunkAndSecurityHeader);
   }
@@ -1842,7 +2091,7 @@
   m_request->writeInt(static_cast<int32_t>(1));  // len is 1
   m_request->write(static_cast<int8_t>(0));      // is obj is '0'.
   // cast away constness here since we want to modify this
-  TcrMessage::m_keepalive = const_cast<uint8_t*>(m_request->getCursor());
+  TcrMessage::m_keepAlive = const_cast<uint8_t*>(m_request->getCursor());
   m_request->write(static_cast<int8_t>(0));  // keepalive is '0'.
 }
 
@@ -1925,7 +2174,7 @@
   m_receiveValues = receiveValues;
 
   auto numInItrestList = keys.size();
-  GF_R_ASSERT(numInItrestList != 0);
+  assert(numInItrestList != 0);
   uint32_t numOfParts = 2 + static_cast<uint32_t>(numInItrestList);
 
   numOfParts += 2;
@@ -2099,7 +2348,6 @@
   m_request.reset(dataOutput);
 
   uint32_t numParts = static_cast<uint32_t>(entries.size());
-  GF_D_ASSERT(numParts > 0);
   writeHeader(m_msgType, numParts);
   for (EventIdMapEntryList::const_iterator entry = entries.begin();
        entry != entries.end(); ++entry) {
@@ -2228,16 +2476,6 @@
   writeMessageLength();
 }
 
-TcrMessageUpdateClientNotification::TcrMessageUpdateClientNotification(
-    DataOutput* dataOutput, int32_t port) {
-  m_msgType = TcrMessage::UPDATE_CLIENT_NOTIFICATION;
-  m_request.reset(dataOutput);
-
-  writeHeader(m_msgType, 1);
-  writeIntPart(port);
-  writeMessageLength();
-}
-
 TcrMessageGetAll::TcrMessageGetAll(
     DataOutput* dataOutput, const Region* region,
     const std::vector<std::shared_ptr<CacheableKey>>* keys,
@@ -2564,7 +2802,7 @@
   writeObjectPart(encryptBytes);
 
   writeMessageLength();
-  LOGDEBUG("TcrMessage CUCM() = %s ",
+  LOGDEBUG("TcrMessage::createUserCredentialMessage  msg = %s ",
            Utils::convertBytesToString(m_request->getBuffer(),
                                        m_request->getBufferLength())
                .c_str());
@@ -2594,13 +2832,16 @@
 
   auto encryptBytes = conn->encryptBytes(bytes);
 
+  LOGDEBUG("TcrMessage::addSecurityPart [%p] length = %" PRId32
+           ", encrypted ID = %s ",
+           conn, encryptBytes->length(),
+           Utils::convertBytesToString(encryptBytes->value().data(),
+                                       encryptBytes->length())
+               .c_str());
+
   writeObjectPart(encryptBytes);
   writeMessageLength();
   m_securityHeaderLength = 4 + 1 + encryptBytes->length();
-  LOGDEBUG("TcrMessage addsp = %s ",
-           Utils::convertBytesToString(m_request->getBuffer(),
-                                       m_request->getBufferLength())
-               .c_str());
 }
 
 void TcrMessage::addSecurityPart(int64_t connectionId, TcrConnection* conn) {
@@ -2965,6 +3206,130 @@
   }
 }
 
+bool TcrMessageHelper::readExceptionPart(TcrMessage& msg, DataInput& input,
+                                         uint8_t isLastChunk) {
+  return msg.readExceptionPart(input, isLastChunk);
+}
+
+void TcrMessageHelper::skipParts(TcrMessage& msg, DataInput& input,
+                                 int32_t numParts) {
+  msg.skipParts(input, numParts);
+}
+
+TcrMessageHelper::ChunkObjectType TcrMessageHelper::readChunkPartHeader(
+    TcrMessage& msg, DataInput& input, DSCode expectedFirstType,
+    int32_t expectedPartType, const char* methodName, uint32_t& partLen,
+    uint8_t isLastChunk) {
+  partLen = input.readInt32();
+  const auto isObj = input.readBoolean();
+
+  if (partLen == 0) {
+    // special null object is case for scalar query result
+    return ChunkObjectType::NULL_OBJECT;
+  } else if (!isObj) {
+    // otherwise we're currently always expecting an object
+    char exMsg[256];
+    std::snprintf(exMsg, sizeof(exMsg),
+                  "TcrMessageHelper::readChunkPartHeader: "
+                  "%s: part is not object",
+                  methodName);
+    LOGDEBUG("%s ", exMsg);
+    return ChunkObjectType::EXCEPTION;
+  }
+
+  auto rawByte = input.read();
+  auto partType = static_cast<DSCode>(rawByte);
+  auto compId = static_cast<int32_t>(partType);
+
+  //  ugly hack to check for exception chunk
+  if (partType == DSCode::JavaSerializable) {
+    input.reset();
+    if (TcrMessageHelper::readExceptionPart(msg, input, isLastChunk)) {
+      msg.setMessageType(TcrMessage::EXCEPTION);
+      return ChunkObjectType::EXCEPTION;
+    } else {
+      char exMsg[256];
+      std::snprintf(exMsg, sizeof(exMsg),
+                    "TcrMessageHelper::readChunkPartHeader: %s: cannot handle "
+                    "java serializable object from server",
+                    methodName);
+      throw MessageException(exMsg);
+    }
+  } else if (partType == DSCode::NullObj) {
+    // special null object is case for scalar query result
+    return ChunkObjectType::NULL_OBJECT;
+  }
+
+  // TODO enum - wtf?
+  if (expectedFirstType > DSCode::FixedIDDefault) {
+    if (partType != expectedFirstType) {
+      char exMsg[256];
+      std::snprintf(exMsg, sizeof(exMsg),
+                    "TcrMessageHelper::readChunkPartHeader: "
+                    "%s: got unhandled object class = %" PRId8,
+                    methodName, static_cast<int8_t>(partType));
+      throw MessageException(exMsg);
+    }
+    // This is for GETALL
+    if (expectedFirstType == DSCode::FixedIDShort) {
+      compId = input.readInt16();
+    }  // This is for QUERY or REGISTER INTEREST.
+    else if (expectedFirstType == DSCode::FixedIDByte) {
+      compId = input.read();
+    }
+  }
+  if (compId != expectedPartType) {
+    char exMsg[256];
+    std::snprintf(exMsg, sizeof(exMsg),
+                  "TcrMessageHelper::readChunkPartHeader: "
+                  "%s: got unhandled object type = %d, expected = %d, raw = %d",
+                  methodName, compId, expectedPartType, rawByte);
+    throw MessageException(exMsg);
+  }
+  return ChunkObjectType::OBJECT;
+}
+
+TcrMessageHelper::ChunkObjectType TcrMessageHelper::readChunkPartHeader(
+    TcrMessage& msg, DataInput& input, const char* methodName,
+    uint32_t& partLen, uint8_t isLastChunk) {
+  partLen = input.readInt32();
+  const auto isObj = input.readBoolean();
+
+  if (partLen == 0) {
+    // special null object is case for scalar query result
+    return ChunkObjectType::NULL_OBJECT;
+  } else if (!isObj) {
+    // otherwise we're currently always expecting an object
+    char exMsg[256];
+    std::snprintf(exMsg, 255,
+                  "TcrMessageHelper::readChunkPartHeader: "
+                  "%s: part is not object",
+                  methodName);
+    throw MessageException(exMsg);
+  }
+
+  const auto partType = static_cast<const DSCode>(input.read());
+  //  ugly hack to check for exception chunk
+  if (partType == DSCode::JavaSerializable) {
+    input.reset();
+    if (TcrMessageHelper::readExceptionPart(msg, input, isLastChunk)) {
+      msg.setMessageType(TcrMessage::EXCEPTION);
+      return ChunkObjectType::EXCEPTION;
+    } else {
+      char exMsg[256];
+      std::snprintf(exMsg, 255,
+                    "TcrMessageHelper::readChunkPartHeader: %s: cannot handle "
+                    "java serializable object from server",
+                    methodName);
+      throw MessageException(exMsg);
+    }
+  } else if (partType == DSCode::NullObj) {
+    // special null object is case for scalar query result
+    return ChunkObjectType::NULL_OBJECT;
+  }
+  return ChunkObjectType::OBJECT;
+}
+
 #pragma error_messages(default, SEC_UNINITIALIZED_MEM_READ)
 
 }  // namespace client
diff --git a/cppcache/src/TcrMessage.hpp b/cppcache/src/TcrMessage.hpp
index 46665c0..f2d2cd7 100644
--- a/cppcache/src/TcrMessage.hpp
+++ b/cppcache/src/TcrMessage.hpp
@@ -50,21 +50,11 @@
 namespace apache {
 namespace geode {
 namespace client {
-
-class TcrMessage;
-class ThinClientRegion;
 class ThinClientBaseDM;
-class TcrMessageHelper;
 class TcrConnection;
 class TcrMessagePing;
 
-class APACHE_GEODE_EXPORT TcrMessage {
- private:
-  inline static void writeInt(uint8_t* buffer, uint16_t value);
-  inline static void writeInt(uint8_t* buffer, uint32_t value);
-  inline static void readInt(uint8_t* buffer, uint16_t* value);
-  inline static void readInt(uint8_t* buffer, uint32_t* value);
-
+class TcrMessage {
  public:
   typedef enum {
     /* Server couldn't read message; handle it like a server side
@@ -180,36 +170,9 @@
 
   } MsgType;
 
-  static bool isKeepAlive() { return *m_keepalive > 0; }
-  static bool isUserInitiativeOps(const TcrMessage& msg) {
-    int32_t msgType = msg.getMessageType();
+  static bool isKeepAlive();
+  static bool isUserInitiativeOps(const TcrMessage& msg);
 
-    if (!msg.isMetaRegion() &&
-        !(msgType == TcrMessage::PING || msgType == TcrMessage::PERIODIC_ACK ||
-          msgType == TcrMessage::MAKE_PRIMARY ||
-          msgType == TcrMessage::CLOSE_CONNECTION ||
-          msgType == TcrMessage::CLIENT_READY ||
-          msgType == TcrMessage::INVALID ||
-          msgType == TcrMessage::MONITORCQ_MSG_TYPE ||
-          msgType == TcrMessage::GETCQSTATS_MSG_TYPE ||
-          msgType == TcrMessage::REQUEST_EVENT_VALUE ||
-          msgType == TcrMessage::GET_CLIENT_PR_METADATA ||
-          msgType == TcrMessage::GET_CLIENT_PARTITION_ATTRIBUTES ||
-          msgType == TcrMessage::GET_PDX_ID_FOR_TYPE ||
-          msgType == TcrMessage::GET_PDX_TYPE_BY_ID ||
-          msgType == TcrMessage::ADD_PDX_TYPE || msgType == TcrMessage::SIZE ||
-          msgType == TcrMessage::TX_FAILOVER ||
-          msgType == TcrMessage::GET_ENTRY ||
-          msgType == TcrMessage::TX_SYNCHRONIZATION ||
-          msgType == TcrMessage::GET_FUNCTION_ATTRIBUTES ||
-          msgType == TcrMessage::ADD_PDX_ENUM ||
-          msgType == TcrMessage::GET_PDX_ENUM_BY_ID ||
-          msgType == TcrMessage::GET_PDX_ID_FOR_ENUM ||
-          msgType == TcrMessage::COMMIT || msgType == TcrMessage::ROLLBACK)) {
-      return true;
-    }
-    return false;
-  }
   static std::shared_ptr<VersionTag> readVersionTagPart(
       DataInput& input, uint16_t endpointMemId,
       MemberListForVersionStamp& memberListForVersionStamp);
@@ -221,7 +184,7 @@
 
   void startProcessChunk(ACE_Semaphore& finalizeSema);
   // nullptr chunk means that this is the last chunk
-  void processChunk(const uint8_t* chunk, int32_t chunkLen,
+  void processChunk(const std::vector<uint8_t>& chunk, int32_t chunkLen,
                     uint16_t endpointmemId,
                     const uint8_t isLastChunkAndisSecurityHeader = 0x00);
   /* For creating a region on the java server */
@@ -240,21 +203,11 @@
   // Updates the early ack byte of the message to reflect that it is a retry op
   void updateHeaderForRetry();
 
-  inline const std::vector<std::shared_ptr<CacheableKey>>* getKeys() const {
-    return m_keyList;
-  }
+  const std::vector<std::shared_ptr<CacheableKey>>* getKeys() const;
 
-  inline const std::string& getRegex() const { return m_regex; }
+  const std::string& getRegex() const;
 
-  inline InterestResultPolicy getInterestResultPolicy() const {
-    if (m_interestPolicy == 2) {
-      return InterestResultPolicy::KEYS_VALUES;
-    } else if (m_interestPolicy == 1) {
-      return InterestResultPolicy::KEYS;
-    } else {
-      return InterestResultPolicy::NONE;
-    }
-  }
+  InterestResultPolicy getInterestResultPolicy() const;
 
   Pool* getPool() const;
 
@@ -262,48 +215,13 @@
    * Whether the request is meant to be
    * sent to PR primary node for single hop.
    */
-  inline bool forPrimary() const {
-    return m_msgType == TcrMessage::PUT || m_msgType == TcrMessage::DESTROY ||
-           m_msgType == TcrMessage::EXECUTE_REGION_FUNCTION;
-  }
+  bool forPrimary() const;
 
-  inline void initCqMap() { m_cqs = new std::map<std::string, int>(); }
+  void initCqMap();
 
-  inline bool forSingleHop() const {
-    return m_msgType == TcrMessage::PUT || m_msgType == TcrMessage::DESTROY ||
-           m_msgType == TcrMessage::REQUEST ||
-           m_msgType == TcrMessage::GET_ALL_70 ||
-           m_msgType == TcrMessage::GET_ALL_WITH_CALLBACK ||
-           m_msgType == TcrMessage::EXECUTE_REGION_FUNCTION ||
-           m_msgType == TcrMessage::PUTALL ||
-           m_msgType == TcrMessage::PUT_ALL_WITH_CALLBACK;
-  }
+  bool forSingleHop() const;
 
-  inline bool forTransaction() const { return m_txId != -1; }
-
-  /*
-  inline void getSingleHopFlags(bool& forSingleHop, bool& forPrimary) const
-  {
-    if (m_msgType == TcrMessage::PUT ||
-         m_msgType == TcrMessage::DESTROY ||
-         m_msgType == TcrMessage::REQUEST) {
-
-           forSingleHop = true;
-
-           if (m_msgType == TcrMessage::REQUEST) {
-             forPrimary = false;
-           } else {
-             forPrimary = true;
-           }
-
-    } else {
-
-      forSingleHop = false;
-      forPrimary = false;
-
-    }
-  }
-  */
+  bool forTransaction() const;
 
   /* destroy the connection */
   virtual ~TcrMessage();
@@ -324,11 +242,8 @@
   const std::shared_ptr<Cacheable>& getCallbackArgumentRef() const;
 
   const std::map<std::string, int>* getCqs() const;
-  bool getBoolValue() const { return m_boolValue; };
-  inline const char* getException() {
-    exceptionMessage = Utils::nullSafeToString(m_value);
-    return exceptionMessage.c_str();
-  }
+  bool getBoolValue() const;
+  const char* getException();
 
   const char* getMsgData() const;
   const char* getMsgHeader() const;
@@ -351,53 +266,36 @@
   /* The caller should not delete the message since it is global. */
   static TcrMessage* getCloseConnMessage(CacheImpl* cacheImpl);
   static void setKeepAlive(bool keepalive);
-  bool isDurable() const { return m_isDurable; }
-  bool receiveValues() const { return m_receiveValues; }
-  bool hasCqPart() const { return m_hasCqsPart; }
-  uint32_t getMessageTypeForCq() const { return m_msgTypeForCq; }
-  bool isInterestListPassed() const { return m_isInterestListPassed; }
-  bool shouldIgnore() const { return m_shouldIgnore; }
-  int8_t getMetaDataVersion() const { return m_metaDataVersion; }
-  uint32_t getEntryNotFound() const { return m_entryNotFound; }
-  int8_t getserverGroupVersion() const { return m_serverGroupVersion; }
-  std::vector<int8_t>* getFunctionAttributes() { return m_functionAttributes; }
+  bool isDurable() const;
+  bool receiveValues() const;
+  bool hasCqPart() const;
+  uint32_t getMessageTypeForCq() const;
+  bool isInterestListPassed() const;
+  bool shouldIgnore() const;
+  int8_t getMetaDataVersion() const;
+  uint32_t getEntryNotFound() const;
+  int8_t getserverGroupVersion() const;
+  std::vector<int8_t>* getFunctionAttributes();
 
   // set the DM for chunked response messages
-  void setDM(ThinClientBaseDM* dm) { m_tcdm = dm; }
-
-  ThinClientBaseDM* getDM() { return m_tcdm; }
+  void setDM(ThinClientBaseDM* dm);
+  ThinClientBaseDM* getDM();
   // set the chunked response handler
-  void setChunkedResultHandler(TcrChunkedResult* chunkedResult) {
-    this->m_isLastChunkAndisSecurityHeader = 0x0;
-    m_chunkedResult = chunkedResult;
-  }
-  TcrChunkedResult* getChunkedResultHandler() { return m_chunkedResult; }
+  void setChunkedResultHandler(TcrChunkedResult* chunkedResult);
+  TcrChunkedResult* getChunkedResultHandler();
   void setVersionedObjectPartList(
-      std::shared_ptr<VersionedCacheableObjectPartList> versionObjPartListptr) {
-    m_versionObjPartListptr = versionObjPartListptr;
-  }
+      std::shared_ptr<VersionedCacheableObjectPartList> versionObjPartListptr);
 
   std::shared_ptr<VersionedCacheableObjectPartList>
-  getVersionedObjectPartList() {
-    return m_versionObjPartListptr;
-  }
+  getVersionedObjectPartList();
 
-  DataInput* getDelta() { return m_delta.get(); }
-
+  DataInput* getDelta();
   //  getDeltaBytes( ) is called *only* by CqService, returns a CacheableBytes
   //  that
   // takes ownership of delta bytes.
-  std::shared_ptr<CacheableBytes> getDeltaBytes() {
-    if (m_deltaBytes == nullptr) {
-      return nullptr;
-    }
-    auto retVal = CacheableBytes::create(
-        std::vector<int8_t>(m_deltaBytes, m_deltaBytes + m_deltaBytesLen));
-    m_deltaBytes = nullptr;
-    return retVal;
-  }
+  std::shared_ptr<CacheableBytes> getDeltaBytes();
 
-  bool hasDelta() { return (m_delta != nullptr); }
+  bool hasDelta();
 
   void addSecurityPart(int64_t connectionId, int64_t unique_id,
                        TcrConnection* conn);
@@ -416,114 +314,38 @@
 
   void readUniqueIDObjectPart(DataInput& input);
 
-  void setMetaRegion(bool isMetaRegion) { m_isMetaRegion = isMetaRegion; }
+  void setMetaRegion(bool isMetaRegion);
+  bool isMetaRegion() const;
 
-  bool isMetaRegion() const { return m_isMetaRegion; }
+  int32_t getNumBuckets() const;
 
-  int32_t getNumBuckets() const { return m_bucketCount; }
+  const std::string& getColocatedWith() const;
 
-  const std::string& getColocatedWith() const { return m_colocatedWith; }
-
-  const std::string& getPartitionResolver() const {
-    return m_partitionResolverName;
-  }
+  const std::string& getPartitionResolver() const;
 
   std::vector<std::vector<std::shared_ptr<BucketServerLocation>>>*
-  getMetadata() {
-    return m_metadata;
-  }
+  getMetadata();
 
-  std::vector<std::shared_ptr<FixedPartitionAttributesImpl>>* getFpaSet() {
-    return m_fpaSet;
-  }
+  std::vector<std::shared_ptr<FixedPartitionAttributesImpl>>* getFpaSet();
 
-  std::shared_ptr<CacheableHashSet> getFailedNode() { return m_failedNode; }
+  std::shared_ptr<CacheableHashSet> getFailedNode();
 
-  bool isCallBackArguement() const { return m_isCallBackArguement; }
+  bool isCallBackArguement() const;
 
-  void setCallBackArguement(bool aCallBackArguement) {
-    m_isCallBackArguement = aCallBackArguement;
-  }
+  void setCallBackArguement(bool aCallBackArguement);
 
   void setBucketServerLocation(
-      std::shared_ptr<BucketServerLocation> serverLocation) {
-    m_bucketServerLocation = serverLocation;
-  }
-  void setVersionTag(std::shared_ptr<VersionTag> versionTag) {
-    m_versionTag = versionTag;
-  }
-  std::shared_ptr<VersionTag> getVersionTag() { return m_versionTag; }
-  uint8_t hasResult() const { return m_hasResult; }
-  std::shared_ptr<CacheableHashMap> getTombstoneVersions() const {
-    return m_tombstoneVersions;
-  }
-  std::shared_ptr<CacheableHashSet> getTombstoneKeys() const {
-    return m_tombstoneKeys;
-  }
+      std::shared_ptr<BucketServerLocation> serverLocation);
+  void setVersionTag(std::shared_ptr<VersionTag> versionTag);
+  std::shared_ptr<VersionTag> getVersionTag();
+  uint8_t hasResult() const;
+  std::shared_ptr<CacheableHashMap> getTombstoneVersions() const;
+  std::shared_ptr<CacheableHashSet> getTombstoneKeys() const;
 
   bool isFEAnotherHop();
 
  protected:
-  TcrMessage()
-      : m_request(nullptr),
-        m_tcdm(nullptr),
-        m_chunkedResult(nullptr),
-        m_keyList(nullptr),
-        m_region(nullptr),
-        m_timeout(15 /*DEFAULT_TIMEOUT_SECONDS*/),
-        m_metadata(),
-        m_cqs(nullptr),
-        m_messageResponseTimeout(-1),
-        m_delta(nullptr),
-        m_deltaBytes(nullptr),
-        m_fpaSet(),
-        m_functionAttributes(),
-        m_connectionIDBytes(nullptr),
-        m_creds(),
-        m_key(),
-        m_value(nullptr),
-        m_failedNode(),
-        m_callbackArgument(nullptr),
-        m_versionTag(),
-        m_eventid(nullptr),
-        m_vectorPtr(),
-        m_bucketServerLocation(nullptr),
-        m_tombstoneVersions(),
-        m_tombstoneKeys(),
-        m_versionObjPartListptr(),
-        exceptionMessage(),
-        m_regionName("INVALID_REGION_NAME"),
-        m_regex(),
-        m_bucketServerLocations(),
-        m_colocatedWith(),
-        m_partitionResolverName(),
-        m_securityHeaderLength(0),
-        m_msgType(TcrMessage::INVALID),
-        m_msgLength(-1),
-        m_msgTypeRequest(0),
-        m_txId(-1),
-        m_bucketCount(0),
-        m_numCqPart(0),
-        m_msgTypeForCq(0),
-        m_deltaBytesLen(0),
-        m_entryNotFound(0),
-        m_feAnotherHop(false),
-        isSecurityOn(false),
-        m_isLastChunkAndisSecurityHeader(0),
-        m_isSecurityHeaderAdded(false),
-        m_isMetaRegion(false),
-        m_decodeAll(false),
-        m_interestPolicy(0),
-        m_isDurable(false),
-        m_receiveValues(false),
-        m_hasCqsPart(false),
-        m_isInterestListPassed(false),
-        m_shouldIgnore(false),
-        m_metaDataVersion(0),
-        m_serverGroupVersion(0),
-        m_boolValue(0),
-        m_isCallBackArguement(false),
-        m_hasResult(0) {}
+  TcrMessage();
 
   void handleSpecialFECase();
   void writeBytesOnly(const std::shared_ptr<Serializable>& se);
@@ -569,8 +391,8 @@
   void writeMillisecondsPart(std::chrono::milliseconds millis);
   void writeByteAndTimeOutPart(uint8_t byteValue,
                                std::chrono::milliseconds timeout);
-  void chunkSecurityHeader(int skipParts, const uint8_t* bytes, int32_t len,
-                           uint8_t isLastChunkAndSecurityHeader);
+  void chunkSecurityHeader(int skipParts, const std::vector<uint8_t> bytes,
+                           int32_t len, uint8_t isLastChunkAndSecurityHeader);
 
   void readEventIdPart(DataInput& input, bool skip = false,
                        int32_t parts = 1);  // skip num parts then read eventid
@@ -649,7 +471,7 @@
   uint8_t m_hasResult;
 
   static std::atomic<int32_t> m_transactionId;
-  static uint8_t* m_keepalive;
+  static uint8_t* m_keepAlive;
   const static int m_flag_empty;
   const static int m_flag_concurrency_checks;
 
@@ -664,9 +486,7 @@
       std::chrono::milliseconds messageResponsetimeout,
       ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageDestroyRegion() {}
-
- private:
+  ~TcrMessageDestroyRegion() override = default;
 };
 
 class TcrMessageClearRegion : public TcrMessage {
@@ -676,9 +496,7 @@
                         std::chrono::milliseconds messageResponsetimeout,
                         ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageClearRegion() {}
-
- private:
+  ~TcrMessageClearRegion() override = default;
 };
 
 class TcrMessageQuery : public TcrMessage {
@@ -687,9 +505,7 @@
                   std::chrono::milliseconds messageResponsetimeout,
                   ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageQuery() {}
-
- private:
+  ~TcrMessageQuery() override = default;
 };
 
 class TcrMessageStopCQ : public TcrMessage {
@@ -698,9 +514,7 @@
                    std::chrono::milliseconds messageResponsetimeout,
                    ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageStopCQ() {}
-
- private:
+  ~TcrMessageStopCQ() override = default;
 };
 
 class TcrMessageCloseCQ : public TcrMessage {
@@ -709,9 +523,7 @@
                     std::chrono::milliseconds messageResponsetimeout,
                     ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageCloseCQ() {}
-
- private:
+  ~TcrMessageCloseCQ() override = default;
 };
 
 class TcrMessageQueryWithParameters : public TcrMessage {
@@ -723,9 +535,7 @@
       std::chrono::milliseconds messageResponsetimeout,
       ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageQueryWithParameters() {}
-
- private:
+  ~TcrMessageQueryWithParameters() override = default;
 };
 
 class TcrMessageContainsKey : public TcrMessage {
@@ -735,9 +545,7 @@
                         const std::shared_ptr<Serializable>& aCallbackArgument,
                         bool isContainsKey, ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageContainsKey() {}
-
- private:
+  ~TcrMessageContainsKey() override = default;
 };
 
 class TcrMessageGetDurableCqs : public TcrMessage {
@@ -745,9 +553,7 @@
   TcrMessageGetDurableCqs(DataOutput* dataOutput,
                           ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageGetDurableCqs() {}
-
- private:
+  ~TcrMessageGetDurableCqs() override = default;
 };
 
 class TcrMessageRequest : public TcrMessage {
@@ -757,9 +563,7 @@
                     const std::shared_ptr<Serializable>& aCallbackArgument,
                     ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageRequest() {}
-
- private:
+  ~TcrMessageRequest() override = default;
 };
 
 class TcrMessageInvalidate : public TcrMessage {
@@ -769,7 +573,7 @@
                        const std::shared_ptr<Serializable>& aCallbackArgument,
                        ThinClientBaseDM* connectionDM = nullptr);
 
- private:
+  ~TcrMessageInvalidate() override = default;
 };
 
 class TcrMessageDestroy : public TcrMessage {
@@ -780,7 +584,7 @@
                     const std::shared_ptr<Serializable>& aCallbackArgument,
                     ThinClientBaseDM* connectionDM = nullptr);
 
- private:
+  ~TcrMessageDestroy() override = default;
 };
 
 class TcrMessageRegisterInterestList : public TcrMessage {
@@ -793,9 +597,7 @@
       InterestResultPolicy interestPolicy = InterestResultPolicy::NONE,
       ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageRegisterInterestList() {}
-
- private:
+  ~TcrMessageRegisterInterestList() override = default;
 };
 
 class TcrMessageUnregisterInterestList : public TcrMessage {
@@ -807,9 +609,7 @@
       InterestResultPolicy interestPolicy = InterestResultPolicy::NONE,
       ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageUnregisterInterestList() {}
-
- private:
+  ~TcrMessageUnregisterInterestList() override = default;
 };
 
 class TcrMessagePut : public TcrMessage {
@@ -822,9 +622,7 @@
                 bool isMetaRegion = false, bool fullValueAfterDeltaFail = false,
                 const char* regionName = nullptr);
 
-  virtual ~TcrMessagePut() {}
-
- private:
+  ~TcrMessagePut() override = default;
 };
 
 class TcrMessageCreateRegion : public TcrMessage {
@@ -834,9 +632,7 @@
                          bool receiveValues = true,
                          ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageCreateRegion() {}
-
- private:
+  ~TcrMessageCreateRegion() override = default;
 };
 
 class TcrMessageRegisterInterest : public TcrMessage {
@@ -847,9 +643,7 @@
       bool isDurable = false, bool isCachingEnabled = false,
       bool receiveValues = true, ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageRegisterInterest() {}
-
- private:
+  ~TcrMessageRegisterInterest() override = default;
 };
 
 class TcrMessageUnregisterInterest : public TcrMessage {
@@ -860,9 +654,7 @@
       bool isDurable = false, bool receiveValues = true,
       ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageUnregisterInterest() {}
-
- private:
+  ~TcrMessageUnregisterInterest() override = default;
 };
 
 class TcrMessageTxSynchronization : public TcrMessage {
@@ -870,54 +662,42 @@
   TcrMessageTxSynchronization(DataOutput* dataOutput, int ordinal, int txid,
                               int status);
 
-  virtual ~TcrMessageTxSynchronization() {}
-
- private:
+  ~TcrMessageTxSynchronization() override = default;
 };
 
 class TcrMessageClientReady : public TcrMessage {
  public:
   explicit TcrMessageClientReady(DataOutput* dataOutput);
 
-  virtual ~TcrMessageClientReady() {}
-
- private:
+  ~TcrMessageClientReady() override = default;
 };
 
 class TcrMessageCommit : public TcrMessage {
  public:
   explicit TcrMessageCommit(DataOutput* dataOutput);
 
-  virtual ~TcrMessageCommit() {}
-
- private:
+  ~TcrMessageCommit() override = default;
 };
 
 class TcrMessageRollback : public TcrMessage {
  public:
   explicit TcrMessageRollback(DataOutput* dataOutput);
 
-  virtual ~TcrMessageRollback() {}
-
- private:
+  ~TcrMessageRollback() override = default;
 };
 
 class TcrMessageTxFailover : public TcrMessage {
  public:
   explicit TcrMessageTxFailover(DataOutput* dataOutput);
 
-  virtual ~TcrMessageTxFailover() {}
-
- private:
+  ~TcrMessageTxFailover() override = default;
 };
 
 class TcrMessageMakePrimary : public TcrMessage {
  public:
   TcrMessageMakePrimary(DataOutput* dataOutput, bool processedMarker);
 
-  virtual ~TcrMessageMakePrimary() {}
-
- private:
+  ~TcrMessageMakePrimary() override = default;
 };
 
 class TcrMessagePutAll : public TcrMessage {
@@ -928,9 +708,7 @@
                    ThinClientBaseDM* connectionDM,
                    const std::shared_ptr<Serializable>& aCallbackArgument);
 
-  virtual ~TcrMessagePutAll() {}
-
- private:
+  ~TcrMessagePutAll() override = default;
 };
 
 class TcrMessageRemoveAll : public TcrMessage {
@@ -940,9 +718,7 @@
                       const std::shared_ptr<Serializable>& aCallbackArgument,
                       ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageRemoveAll() {}
-
- private:
+  ~TcrMessageRemoveAll() override = default;
 };
 
 class TcrMessageExecuteCq : public TcrMessage {
@@ -951,9 +727,7 @@
                       const std::string& str2, CqState state, bool isDurable,
                       ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageExecuteCq() {}
-
- private:
+  ~TcrMessageExecuteCq() override = default;
 };
 
 class TcrMessageExecuteCqWithIr : public TcrMessage {
@@ -962,9 +736,7 @@
                             const std::string& str2, CqState state,
                             bool isDurable, ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageExecuteCqWithIr() {}
-
- private:
+  ~TcrMessageExecuteCqWithIr() override = default;
 };
 
 class TcrMessageExecuteRegionFunction : public TcrMessage {
@@ -977,9 +749,7 @@
       std::chrono::milliseconds timeout,
       ThinClientBaseDM* connectionDM = nullptr, int8_t reExecute = 0);
 
-  virtual ~TcrMessageExecuteRegionFunction() {}
-
- private:
+  ~TcrMessageExecuteRegionFunction() override = default;
 };
 
 class TcrMessageExecuteRegionFunctionSingleHop : public TcrMessage {
@@ -991,9 +761,7 @@
       std::shared_ptr<CacheableHashSet> failedNodes, bool allBuckets,
       std::chrono::milliseconds timeout, ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageExecuteRegionFunctionSingleHop() {}
-
- private:
+  ~TcrMessageExecuteRegionFunctionSingleHop() override = default;
 };
 
 class TcrMessageGetClientPartitionAttributes : public TcrMessage {
@@ -1001,27 +769,21 @@
   TcrMessageGetClientPartitionAttributes(DataOutput* dataOutput,
                                          const char* regionName);
 
-  virtual ~TcrMessageGetClientPartitionAttributes() {}
-
- private:
+  ~TcrMessageGetClientPartitionAttributes() override = default;
 };
 
 class TcrMessageGetClientPrMetadata : public TcrMessage {
  public:
   TcrMessageGetClientPrMetadata(DataOutput* dataOutput, const char* regionName);
 
-  virtual ~TcrMessageGetClientPrMetadata() {}
-
- private:
+  ~TcrMessageGetClientPrMetadata() override = default;
 };
 
 class TcrMessageSize : public TcrMessage {
  public:
   TcrMessageSize(DataOutput* dataOutput, const char* regionName);
 
-  virtual ~TcrMessageSize() {}
-
- private:
+  ~TcrMessageSize() override = default;
 };
 
 class TcrMessageUserCredential : public TcrMessage {
@@ -1030,9 +792,7 @@
                            std::shared_ptr<Properties> creds,
                            ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageUserCredential() {}
-
- private:
+  ~TcrMessageUserCredential() override = default;
 };
 
 class TcrMessageRemoveUserAuth : public TcrMessage {
@@ -1040,9 +800,7 @@
   TcrMessageRemoveUserAuth(DataOutput* dataOutput, bool keepAlive,
                            ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageRemoveUserAuth() {}
-
- private:
+  ~TcrMessageRemoveUserAuth() override = default;
 };
 
 class TcrMessageGetPdxIdForType : public TcrMessage {
@@ -1051,9 +809,7 @@
                             const std::shared_ptr<Cacheable>& pdxType,
                             ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageGetPdxIdForType() {}
-
- private:
+  ~TcrMessageGetPdxIdForType() override = default;
 };
 
 class TcrMessageAddPdxType : public TcrMessage {
@@ -1062,9 +818,7 @@
                        const std::shared_ptr<Cacheable>& pdxType,
                        ThinClientBaseDM* connectionDM, int32_t pdxTypeId = 0);
 
-  virtual ~TcrMessageAddPdxType() {}
-
- private:
+  ~TcrMessageAddPdxType() override = default;
 };
 
 class TcrMessageGetPdxIdForEnum : public TcrMessage {
@@ -1073,9 +827,7 @@
                             const std::shared_ptr<Cacheable>& pdxType,
                             ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageGetPdxIdForEnum() {}
-
- private:
+  ~TcrMessageGetPdxIdForEnum() override = default;
 };
 
 class TcrMessageAddPdxEnum : public TcrMessage {
@@ -1084,9 +836,7 @@
                        const std::shared_ptr<Cacheable>& pdxType,
                        ThinClientBaseDM* connectionDM, int32_t pdxTypeId = 0);
 
-  virtual ~TcrMessageAddPdxEnum() {}
-
- private:
+  ~TcrMessageAddPdxEnum() override = default;
 };
 
 class TcrMessageGetPdxTypeById : public TcrMessage {
@@ -1094,9 +844,7 @@
   TcrMessageGetPdxTypeById(DataOutput* dataOutput, int32_t typeId,
                            ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageGetPdxTypeById() {}
-
- private:
+  ~TcrMessageGetPdxTypeById() override = default;
 };
 
 class TcrMessageGetPdxEnumById : public TcrMessage {
@@ -1104,9 +852,7 @@
   TcrMessageGetPdxEnumById(DataOutput* dataOutput, int32_t typeId,
                            ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageGetPdxEnumById() {}
-
- private:
+  ~TcrMessageGetPdxEnumById() override = default;
 };
 
 class TcrMessageGetFunctionAttributes : public TcrMessage {
@@ -1115,9 +861,7 @@
                                   const std::string& funcName,
                                   ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageGetFunctionAttributes() {}
-
- private:
+  ~TcrMessageGetFunctionAttributes() override = default;
 };
 
 class TcrMessageKeySet : public TcrMessage {
@@ -1125,9 +869,7 @@
   TcrMessageKeySet(DataOutput* dataOutput, const std::string& funcName,
                    ThinClientBaseDM* connectionDM = nullptr);
 
-  virtual ~TcrMessageKeySet() {}
-
- private:
+  ~TcrMessageKeySet() override = default;
 };
 
 class TcrMessageRequestEventValue : public TcrMessage {
@@ -1135,9 +877,7 @@
   TcrMessageRequestEventValue(DataOutput* dataOutput,
                               std::shared_ptr<EventId> eventId);
 
-  virtual ~TcrMessageRequestEventValue() {}
-
- private:
+  ~TcrMessageRequestEventValue() override = default;
 };
 
 class TcrMessagePeriodicAck : public TcrMessage {
@@ -1145,18 +885,7 @@
   TcrMessagePeriodicAck(DataOutput* dataOutput,
                         const EventIdMapEntryList& entries);
 
-  virtual ~TcrMessagePeriodicAck() {}
-
- private:
-};
-
-class TcrMessageUpdateClientNotification : public TcrMessage {
- public:
-  TcrMessageUpdateClientNotification(DataOutput* dataOutput, int32_t port);
-
-  virtual ~TcrMessageUpdateClientNotification() {}
-
- private:
+  ~TcrMessagePeriodicAck() override = default;
 };
 
 class TcrMessageGetAll : public TcrMessage {
@@ -1167,9 +896,7 @@
       ThinClientBaseDM* connectionDM = nullptr,
       const std::shared_ptr<Serializable>& aCallbackArgument = nullptr);
 
-  virtual ~TcrMessageGetAll() {}
-
- private:
+  ~TcrMessageGetAll() override = default;
 };
 
 class TcrMessageExecuteFunction : public TcrMessage {
@@ -1179,43 +906,35 @@
                             uint8_t getResult, ThinClientBaseDM* connectionDM,
                             std::chrono::milliseconds timeout);
 
-  virtual ~TcrMessageExecuteFunction() {}
-
- private:
+  ~TcrMessageExecuteFunction() override = default;
 };
 
 class TcrMessagePing : public TcrMessage {
  public:
   TcrMessagePing(DataOutput* dataOutput, bool decodeAll);
 
-  virtual ~TcrMessagePing() {}
-
- private:
+  ~TcrMessagePing() override = default;
 };
 
 class TcrMessageCloseConnection : public TcrMessage {
  public:
   TcrMessageCloseConnection(DataOutput* dataOutput, bool decodeAll);
 
-  virtual ~TcrMessageCloseConnection() {}
-
- private:
+  ~TcrMessageCloseConnection() override = default;
 };
 
 class TcrMessageClientMarker : public TcrMessage {
  public:
   TcrMessageClientMarker(DataOutput* dataOutput, bool decodeAll);
 
-  virtual ~TcrMessageClientMarker() {}
-
- private:
+  ~TcrMessageClientMarker() override = default;
 };
 
 class TcrMessageReply : public TcrMessage {
  public:
   TcrMessageReply(bool decodeAll, ThinClientBaseDM* connectionDM);
 
-  virtual ~TcrMessageReply() {}
+  ~TcrMessageReply() override = default;
 };
 
 /**
@@ -1224,24 +943,22 @@
  */
 class TcrMessageHelper {
  public:
+  TcrMessageHelper() = delete;
+
   /**
    * result types returned by readChunkPartHeader
    */
-  enum class ChunkObjectType { OBJECT = 0, EXCEPTION = 1, NULL_OBJECT = 2 };
+  enum class ChunkObjectType { OBJECT, EXCEPTION, NULL_OBJECT };
 
   /**
    * Tries to read an exception part and returns true if the exception
    * was successfully read.
    */
-  inline static bool readExceptionPart(TcrMessage& msg, DataInput& input,
-                                       uint8_t isLastChunk) {
-    return msg.readExceptionPart(input, isLastChunk);
-  }
+  static bool readExceptionPart(TcrMessage& msg, DataInput& input,
+                                uint8_t isLastChunk);
 
-  inline static void skipParts(TcrMessage& msg, DataInput& input,
-                               int32_t numParts = 1) {
-    msg.skipParts(input, numParts);
-  }
+  static void skipParts(TcrMessage& msg, DataInput& input,
+                        int32_t numParts = 1);
 
   /**
    * Reads header of a chunk part. Returns true if header was successfully
@@ -1249,124 +966,17 @@
    * Throws a MessageException with relevant message if an unknown
    * message type is encountered in the header.
    */
-  inline static ChunkObjectType readChunkPartHeader(
-      TcrMessage& msg, DataInput& input, DSCode expectedFirstType,
-      int32_t expectedPartType, const char* methodName, uint32_t& partLen,
-      uint8_t isLastChunk) {
-    partLen = input.readInt32();
-    const auto isObj = input.readBoolean();
+  static ChunkObjectType readChunkPartHeader(TcrMessage& msg, DataInput& input,
+                                             DSCode expectedFirstType,
+                                             int32_t expectedPartType,
+                                             const char* methodName,
+                                             uint32_t& partLen,
+                                             uint8_t isLastChunk);
 
-    if (partLen == 0) {
-      // special null object is case for scalar query result
-      return ChunkObjectType::NULL_OBJECT;
-    } else if (!isObj) {
-      // otherwise we're currently always expecting an object
-      char exMsg[256];
-      std::snprintf(exMsg, sizeof(exMsg),
-                    "TcrMessageHelper::readChunkPartHeader: "
-                    "%s: part is not object",
-                    methodName);
-      LOGDEBUG("%s ", exMsg);
-      return ChunkObjectType::EXCEPTION;
-    }
-
-    auto rawByte = input.read();
-    auto partType = static_cast<DSCode>(rawByte);
-    auto compId = static_cast<int32_t>(partType);
-
-    //  ugly hack to check for exception chunk
-    if (partType == DSCode::JavaSerializable) {
-      input.reset();
-      if (TcrMessageHelper::readExceptionPart(msg, input, isLastChunk)) {
-        msg.setMessageType(TcrMessage::EXCEPTION);
-        return ChunkObjectType::EXCEPTION;
-      } else {
-        char exMsg[256];
-        std::snprintf(
-            exMsg, sizeof(exMsg),
-            "TcrMessageHelper::readChunkPartHeader: %s: cannot handle "
-            "java serializable object from server",
-            methodName);
-        throw MessageException(exMsg);
-      }
-    } else if (partType == DSCode::NullObj) {
-      // special null object is case for scalar query result
-      return ChunkObjectType::NULL_OBJECT;
-    }
-
-    // TODO enum - wtf?
-    if (expectedFirstType > DSCode::FixedIDDefault) {
-      if (partType != expectedFirstType) {
-        char exMsg[256];
-        std::snprintf(exMsg, sizeof(exMsg),
-                      "TcrMessageHelper::readChunkPartHeader: "
-                      "%s: got unhandled object class = %" PRId8,
-                      methodName, static_cast<int8_t>(partType));
-        throw MessageException(exMsg);
-      }
-      // This is for GETALL
-      if (expectedFirstType == DSCode::FixedIDShort) {
-        compId = input.readInt16();
-      }  // This is for QUERY or REGISTER INTEREST.
-      else if (expectedFirstType == DSCode::FixedIDByte) {
-        compId = input.read();
-      }
-    }
-    if (compId != expectedPartType) {
-      char exMsg[256];
-      std::snprintf(
-          exMsg, sizeof(exMsg),
-          "TcrMessageHelper::readChunkPartHeader: "
-          "%s: got unhandled object type = %d, expected = %d, raw = %d",
-          methodName, compId, expectedPartType, rawByte);
-      throw MessageException(exMsg);
-    }
-    return ChunkObjectType::OBJECT;
-  }
-
-  inline static ChunkObjectType readChunkPartHeader(TcrMessage& msg,
-                                                    DataInput& input,
-                                                    const char* methodName,
-                                                    uint32_t& partLen,
-                                                    uint8_t isLastChunk) {
-    partLen = input.readInt32();
-    const auto isObj = input.readBoolean();
-
-    if (partLen == 0) {
-      // special null object is case for scalar query result
-      return ChunkObjectType::NULL_OBJECT;
-    } else if (!isObj) {
-      // otherwise we're currently always expecting an object
-      char exMsg[256];
-      std::snprintf(exMsg, 255,
-                    "TcrMessageHelper::readChunkPartHeader: "
-                    "%s: part is not object",
-                    methodName);
-      throw MessageException(exMsg);
-    }
-
-    const auto partType = static_cast<const DSCode>(input.read());
-    //  ugly hack to check for exception chunk
-    if (partType == DSCode::JavaSerializable) {
-      input.reset();
-      if (TcrMessageHelper::readExceptionPart(msg, input, isLastChunk)) {
-        msg.setMessageType(TcrMessage::EXCEPTION);
-        return ChunkObjectType::EXCEPTION;
-      } else {
-        char exMsg[256];
-        std::snprintf(
-            exMsg, 255,
-            "TcrMessageHelper::readChunkPartHeader: %s: cannot handle "
-            "java serializable object from server",
-            methodName);
-        throw MessageException(exMsg);
-      }
-    } else if (partType == DSCode::NullObj) {
-      // special null object is case for scalar query result
-      return ChunkObjectType::NULL_OBJECT;
-    }
-    return ChunkObjectType::OBJECT;
-  }
+  static ChunkObjectType readChunkPartHeader(TcrMessage& msg, DataInput& input,
+                                             const char* methodName,
+                                             uint32_t& partLen,
+                                             uint8_t isLastChunk);
 };
 }  // namespace client
 }  // namespace geode
diff --git a/cppcache/src/TcrPoolEndPoint.cpp b/cppcache/src/TcrPoolEndPoint.cpp
index c3ff4c0..7ac81f4 100644
--- a/cppcache/src/TcrPoolEndPoint.cpp
+++ b/cppcache/src/TcrPoolEndPoint.cpp
@@ -40,12 +40,6 @@
 std::shared_ptr<QueryService> TcrPoolEndPoint::getQueryService() {
   return m_dm->getQueryServiceWithoutCheck();
 }
-void TcrPoolEndPoint::sendRequestForChunkedResponse(const TcrMessage& request,
-                                                    TcrMessageReply& reply,
-                                                    TcrConnection* conn) {
-  conn->sendRequestForChunkedResponse(request, request.getMsgLength(), reply,
-                                      request.getTimeout(), reply.getTimeout());
-}
 ThinClientPoolDM* TcrPoolEndPoint::getPoolHADM() { return m_dm; }
 void TcrPoolEndPoint::triggerRedundancyThread() {
   m_dm->triggerRedundancyThread();
diff --git a/cppcache/src/TcrPoolEndPoint.hpp b/cppcache/src/TcrPoolEndPoint.hpp
index ff99479..fc5fbc1 100644
--- a/cppcache/src/TcrPoolEndPoint.hpp
+++ b/cppcache/src/TcrPoolEndPoint.hpp
@@ -39,9 +39,6 @@
   bool checkDupAndAdd(std::shared_ptr<EventId> eventid) override;
   void processMarker() override;
   std::shared_ptr<QueryService> getQueryService() override;
-  void sendRequestForChunkedResponse(const TcrMessage& request,
-                                     TcrMessageReply& reply,
-                                     TcrConnection* conn) override;
   void closeFailedConnection(TcrConnection*& conn) override;
   GfErrType registerDM(bool clientNotification, bool isSecondary = false,
                        bool isActiveEndpoint = false,
diff --git a/cppcache/src/ThinClientBaseDM.cpp b/cppcache/src/ThinClientBaseDM.cpp
index b062915..a1d741a 100644
--- a/cppcache/src/ThinClientBaseDM.cpp
+++ b/cppcache/src/ThinClientBaseDM.cpp
@@ -228,7 +228,6 @@
   }
   LOGFINE("Ending chunk process thread for region %s",
           (m_region ? m_region->getFullPath().c_str() : "(null)"));
-  GF_DEV_ASSERT(m_chunks.size() == 0);
 }
 
 // start the chunk processing thread
diff --git a/cppcache/src/ThinClientDistributionManager.cpp b/cppcache/src/ThinClientDistributionManager.cpp
index 5bf8cfe..a9a30e2 100644
--- a/cppcache/src/ThinClientDistributionManager.cpp
+++ b/cppcache/src/ThinClientDistributionManager.cpp
@@ -58,7 +58,7 @@
               m_endpoints[m_activeEndpoint]->name().c_str());
     } else if (isFatalError(err)) {
       m_connManager.disconnect(this, m_endpoints);
-      GfErrTypeToException("ThinClientDistributionManager::init", err);
+      throwExceptionIfError("ThinClientDistributionManager::init", err);
     }
   }
   ThinClientBaseDM::init();
@@ -157,7 +157,7 @@
        type == TcrMessage::EXECUTE_REGION_FUNCTION ||
        type == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP ||
        type == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE) &&
-      error == GF_TIMOUT) {
+      error == GF_TIMEOUT) {
     forceSelect = true;
   }
 
@@ -178,7 +178,7 @@
            type == TcrMessage::EXECUTE_REGION_FUNCTION ||
            type == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP ||
            type == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE) &&
-          error == GF_TIMOUT) {
+          error == GF_TIMEOUT) {
         return error;
       }
       currentEndpoint = m_activeEndpoint;
@@ -287,23 +287,12 @@
     }
   }
 
-// Postconditions:
-// 1. If initial size of randIndex > 0 && failover was attempted,  final size of
-// randIndex < initial size of randIndex
-// 2. If CONN_NOERR, then m_activeEndpoint > -1, m_activeEndpoint should be
-// connected.
-// 3. Number of endpoints on which DM is registered <= 1
-#if GF_DEVEL_ASSERTS == 1
-  currentEndpoint = m_activeEndpoint;
-  if ((err == GF_NOERR) &&
-      (currentEndpoint < 0 || !m_endpoints[currentEndpoint]->connected())) {
-    LOGWARN(
-        "Current endpoint %s is not connected after failover.",
-        (currentEndpoint < 0 ? "(null)"
-                             : m_endpoints[currentEndpoint]->name().c_str()));
-  }
-#endif
-
+  // Postconditions:
+  // 1. If initial size of randIndex > 0 && failover was attempted,  final size
+  // of randIndex < initial size of randIndex
+  // 2. If CONN_NOERR, then m_activeEndpoint > -1, m_activeEndpoint should be
+  // connected.
+  // 3. Number of endpoints on which DM is registered <= 1
   return err;
 }
 
@@ -381,7 +370,7 @@
       }
     }
     // throw exception if it is not authenticated
-    // GfErrTypeToException("ThinClientDistributionManager::sendUserCredentials",
+    // throwExceptionIfError("ThinClientDistributionManager::sendUserCredentials",
     // err);
   }
 
diff --git a/cppcache/src/ThinClientPoolDM.cpp b/cppcache/src/ThinClientPoolDM.cpp
index f0c9da2..4eaaca9 100644
--- a/cppcache/src/ThinClientPoolDM.cpp
+++ b/cppcache/src/ThinClientPoolDM.cpp
@@ -18,6 +18,7 @@
 #include "ThinClientPoolDM.hpp"
 
 #include <algorithm>
+#include <thread>
 
 #include <ace/INET_Addr.h>
 
@@ -161,16 +162,18 @@
       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();
 
   auto& sysProp = distributedSystem.getSystemProperties();
   // to set security flag at pool level
-  this->m_isSecurityOn = cacheImpl->getAuthInitialize() != nullptr;
+  m_isSecurityOn = cacheImpl->getAuthInitialize() != nullptr;
 
   ACE_TCHAR hostName[256];
   ACE_OS::hostname(hostName, sizeof(hostName) - 1);
@@ -218,17 +221,16 @@
   LOGDEBUG("ThinClientPoolDM::init: Starting pool initialization");
   auto cacheImpl = m_connManager.getCacheImpl();
   auto& sysProp = cacheImpl->getDistributedSystem().getSystemProperties();
-  m_isMultiUserMode = this->getMultiuserAuthentication();
+  m_isMultiUserMode = getMultiuserAuthentication();
 
   if (m_isMultiUserMode) {
     LOGINFO("Multiuser authentication is enabled for pool %s",
             m_poolName.c_str());
   }
   // to set security flag at pool level
-  this->m_isSecurityOn = cacheImpl->getAuthInitialize() != nullptr;
+  m_isSecurityOn = cacheImpl->getAuthInitialize() != nullptr;
 
-  LOGDEBUG("ThinClientPoolDM::init: security in on/off = %d ",
-           this->m_isSecurityOn);
+  LOGDEBUG("ThinClientPoolDM::init: security in on/off = %d ", m_isSecurityOn);
 
   m_connManager.init(true);
 
@@ -430,6 +432,14 @@
     size_t replaceCount =
         m_attrs->getMinConnections() - static_cast<int>(savelist.size());
 
+    LOGDEBUG("Preserving %d connections", savelist.size());
+
+    for (auto savedconn : savelist) {
+      put(savedconn, false);
+    }
+    savelist.clear();
+    int count = 0;
+
     for (std::vector<TcrConnection*>::const_iterator iter = replacelist.begin();
          iter != replacelist.end(); ++iter) {
       TcrConnection* conn = *iter;
@@ -451,7 +461,7 @@
           if (nextIdle > std::chrono::seconds::zero() && nextIdle < _nextIdle) {
             _nextIdle = nextIdle;
           }
-          savelist.push_back(newConn);
+          put(newConn, false);
           if (newConn != conn) {
             GF_SAFE_DELETE_CON(conn);
             removeEPConnections(1, false);
@@ -474,20 +484,19 @@
                 nextIdle < _nextIdle) {
               _nextIdle = nextIdle;
             }
-            savelist.push_back(conn);
+            put(conn, false);
           }
         }
       }
       replaceCount--;
+      count++;
+      if (count % 10 == 0) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(1));
+      }
     }
-
-    LOGDEBUG("Preserving %d connections", savelist.size());
-
-    for (std::vector<TcrConnection*>::const_iterator iter = savelist.begin();
-         iter != savelist.end(); ++iter) {
-      put(*iter, false);
-    }
+    replacelist.clear();
   }
+
   if (m_connManageTaskId >= 0 && isRunning &&
       m_connManager.getCacheImpl()->getExpiryTaskManager().resetTask(
           m_connManageTaskId, _nextIdle)) {
@@ -665,7 +674,7 @@
     err = funcExe->getResult();
     if (err != GF_NOERR) {
       if (funcExe->getException() == nullptr) {
-        if (err == GF_TIMOUT) {
+        if (err == GF_TIMEOUT) {
           getStats().incTimeoutClientOps();
         } else {
           getStats().incFailedClientOps();
@@ -931,7 +940,7 @@
   err = sendSyncRequest(request, reply);
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("Operation Failed", err);
+    throwExceptionIfError("Operation Failed", err);
   } else if (reply.getMessageType() == TcrMessage::EXCEPTION) {
     LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = %s ",
              reply.getException());
@@ -971,7 +980,7 @@
   err = sendSyncRequest(request, reply);
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("Operation Failed", err);
+    throwExceptionIfError("Operation Failed", err);
   } else if (reply.getMessageType() == TcrMessage::EXCEPTION) {
     LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = %s ",
              reply.getException());
@@ -992,7 +1001,7 @@
   err = sendSyncRequest(request, reply);
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("Operation Failed", err);
+    throwExceptionIfError("Operation Failed", err);
   } else if (reply.getMessageType() == TcrMessage::EXCEPTION) {
     LOGDEBUG("ThinClientPoolDM::GetPDXTypeById: Exception = %s ",
              reply.getException());
@@ -1016,7 +1025,7 @@
   err = sendSyncRequest(request, reply);
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("Operation Failed", err);
+    throwExceptionIfError("Operation Failed", err);
   } else if (reply.getMessageType() == TcrMessage::EXCEPTION) {
     LOGDEBUG("ThinClientPoolDM::GetEnumValue: Exception = %s ",
              reply.getException());
@@ -1055,7 +1064,7 @@
   err = sendSyncRequest(request, reply);
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("Operation Failed", err);
+    throwExceptionIfError("Operation Failed", err);
   } else if (reply.getMessageType() == TcrMessage::EXCEPTION) {
     LOGDEBUG("ThinClientPoolDM::GetEnum: Exception = %s ",
              reply.getException());
@@ -1080,7 +1089,7 @@
   err = sendSyncRequest(request, reply);
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("Operation Failed", err);
+    throwExceptionIfError("Operation Failed", err);
   } else if (reply.getMessageType() == TcrMessage::EXCEPTION) {
     LOGDEBUG("ThinClientPoolDM::AddEnum: Exception = %s ",
              reply.getException());
@@ -1206,7 +1215,7 @@
     // if servergroup is there, then verify otherwise you may reach to another
     // group
     if (m_attrs->m_initLocList.size()) {
-      auto&& servGrp = this->getServerGroup();
+      auto&& servGrp = getServerGroup();
       if (servGrp.length() > 0) {
         auto groups = serverLocation->getServerGroups();
         if ((groups != nullptr) && (groups->length() > 0)) {
@@ -1332,8 +1341,8 @@
         type == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP ||
         type == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE)) {
     // set only when message is not query, putall and executeCQ
-    reply.setTimeout(this->getReadTimeout());
-    request.setTimeout(this->getReadTimeout());
+    reply.setTimeout(getReadTimeout());
+    request.setTimeout(getReadTimeout());
   }
 
   bool retryAllEPsOnce = false;
@@ -1362,7 +1371,7 @@
          type == TcrMessage::EXECUTE_REGION_FUNCTION ||
          type == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP ||
          type == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE) &&
-        error == GF_TIMOUT) {
+        error == GF_TIMEOUT) {
       return error;
     }
 
@@ -1373,8 +1382,7 @@
     bool isUserNeedToReAuthenticate = false;
     bool singleHopConnFound = false;
     bool connFound = false;
-    if (!this->m_isMultiUserMode ||
-        (!TcrMessage::isUserInitiativeOps(request))) {
+    if (!m_isMultiUserMode || (!TcrMessage::isUserInitiativeOps(request))) {
       conn = getConnectionFromQueueW(&queueErr, excludeServers, isBGThread,
                                      request, version, singleHopConnFound,
                                      connFound, serverLocation);
@@ -1426,7 +1434,7 @@
         "ThinClientPoolDM::sendSyncRequest: isUserNeedToReAuthenticate = %d ",
         isUserNeedToReAuthenticate);
     LOGDEBUG(
-        "ThinClientPoolDM::sendSyncRequest: m_isMultiUserMode = %d  conn = %d  "
+        "ThinClientPoolDM::sendSyncRequest: m_isMultiUserMode = %d  conn = %p  "
         "type = %d",
         m_isMultiUserMode, conn, type);
 
@@ -1452,14 +1460,14 @@
       GfErrType userCredMsgErr = GF_NOERR;
       bool isServerException = false;
       if (TcrMessage::isUserInitiativeOps(request) &&
-          (this->m_isSecurityOn || this->m_isMultiUserMode)) {
-        if (!this->m_isMultiUserMode && !ep->isAuthenticated()) {
+          (m_isSecurityOn || m_isMultiUserMode)) {
+        if (!m_isMultiUserMode && !ep->isAuthenticated()) {
           // first authenticate him on this endpoint
-          userCredMsgErr = this->sendUserCredentials(
-              this->getCredentials(ep), conn, isBGThread, isServerException);
+          userCredMsgErr = sendUserCredentials(getCredentials(ep), conn,
+                                               isBGThread, isServerException);
         } else if (isUserNeedToReAuthenticate) {
-          userCredMsgErr = this->sendUserCredentials(
-              userAttr->getCredentials(), conn, isBGThread, isServerException);
+          userCredMsgErr = sendUserCredentials(userAttr->getCredentials(), conn,
+                                               isBGThread, isServerException);
         }
       }
 
@@ -1484,7 +1492,7 @@
                                                  // for Sticky conn.
           LOGDEBUG("putting connection back in queue DONE");
         } else {
-          if (error != GF_TIMOUT) removeEPConnections(ep);
+          if (error != GF_TIMEOUT) removeEPConnections(ep);
           // Update stats for the connection that failed.
           removeEPConnections(1, false);
           setStickyNull(isBGThread ||
@@ -1505,11 +1513,11 @@
     }
 
     if (error == GF_NOERR) {
-      if ((this->m_isSecurityOn || this->m_isMultiUserMode)) {
+      if ((m_isSecurityOn || m_isMultiUserMode)) {
         if (reply.getMessageType() == TcrMessage::EXCEPTION) {
           if (isAuthRequireException(reply.getException())) {
             TcrEndpoint* ep = conn->getEndpointObject();
-            if (!this->m_isMultiUserMode) {
+            if (!m_isMultiUserMode) {
               ep->setAuthenticated(false);
             } else if (userAttr != nullptr) {
               userAttr->unAuthenticateEP(ep);
@@ -1564,7 +1572,7 @@
       getStats().setCurClientOps(--m_clientOps);
       if (error == GF_NOERR) {
         getStats().incSucceedClientOps(); /*inc Id for clientOs stat*/
-      } else if (error == GF_TIMOUT) {
+      } else if (error == GF_TIMEOUT) {
         getStats().incTimeoutClientOps();
       } else {
         getStats().incFailedClientOps();
@@ -1584,7 +1592,7 @@
 
   if (error == GF_NOERR) {
     getStats().incSucceedClientOps();
-  } else if (error == GF_TIMOUT) {
+  } else if (error == GF_TIMEOUT) {
     getStats().incTimeoutClientOps();
   } else {
     getStats().incFailedClientOps();
@@ -1728,7 +1736,7 @@
                                          ->getDistributedSystem()
                                          .getSystemProperties()
                                          .connectTimeout(),
-                                     false, true, appThreadrequest);
+                                     false, appThreadrequest);
   if (conn == nullptr || error != GF_NOERR) {
     LOGFINE("2Failed to connect to %s", theEP->name().c_str());
     if (conn != nullptr) _GEODE_SAFE_DELETE(conn);
@@ -1940,7 +1948,7 @@
           type == TcrMessage::EXECUTE_REGION_FUNCTION ||
           type == TcrMessage::EXECUTE_REGION_FUNCTION_SINGLE_HOP ||
           type == TcrMessage::EXECUTECQ_WITH_IR_MSG_TYPE)) {
-      reply.setTimeout(this->getReadTimeout());
+      reply.setTimeout(getReadTimeout());
     }
 
     reply.setDM(this);
@@ -1948,24 +1956,24 @@
     // in multi user mode need to chk whether user is authenticated or not
     // and then follow usual process which we did in send syncrequest.
     // need to user initiative ops
-    LOGDEBUG("ThinClientPoolDM::sendRequestToEP: this->m_isMultiUserMode = %d",
-             this->m_isMultiUserMode);
+    LOGDEBUG("ThinClientPoolDM::sendRequestToEP: m_isMultiUserMode = %d",
+             m_isMultiUserMode);
     bool isServerException = false;
     if (TcrMessage::isUserInitiativeOps((request)) &&
-        (this->m_isSecurityOn || this->m_isMultiUserMode)) {
-      if (!this->m_isMultiUserMode && !currentEndpoint->isAuthenticated()) {
+        (m_isSecurityOn || m_isMultiUserMode)) {
+      if (!m_isMultiUserMode && !currentEndpoint->isAuthenticated()) {
         // first authenticate him on this endpoint
-        error = this->sendUserCredentials(this->getCredentials(currentEndpoint),
-                                          conn, false, isServerException);
-      } else if (this->m_isMultiUserMode) {
+        error = sendUserCredentials(getCredentials(currentEndpoint), conn,
+                                    false, isServerException);
+      } else if (m_isMultiUserMode) {
         ua = UserAttributes::threadLocalUserAttributes;
         if (ua) {
           UserConnectionAttributes* uca =
               ua->getConnectionAttribute(currentEndpoint);
 
           if (uca == nullptr) {
-            error = this->sendUserCredentials(ua->getCredentials(), conn, false,
-                                              isServerException);
+            error = sendUserCredentials(ua->getCredentials(), conn, false,
+                                        isServerException);
           }
         } else {
           LOGWARN("Attempted operation type %d without credentials",
@@ -2012,10 +2020,10 @@
 
     if (error == GF_NOERR || error == GF_CACHESERVER_EXCEPTION ||
         error == GF_AUTHENTICATION_REQUIRED_EXCEPTION) {
-      if ((this->m_isSecurityOn || this->m_isMultiUserMode)) {
+      if ((m_isSecurityOn || m_isMultiUserMode)) {
         if (reply.getMessageType() == TcrMessage::EXCEPTION) {
           if (isAuthRequireException(reply.getException())) {
-            if (!this->m_isMultiUserMode) {
+            if (!m_isMultiUserMode) {
               currentEndpoint->setAuthenticated(false);
             } else if (ua != nullptr) {
               ua->unAuthenticateEP(currentEndpoint);
@@ -2055,8 +2063,6 @@
     if (m_endpoints.emplace(endpointName, ep).second) {
       LOGERROR("Failed to add endpoint %s to pool %s", endpointName.c_str(),
                m_poolName.c_str());
-      GF_DEV_ASSERT(
-          "ThinClientPoolDM::addEP( ): failed to add endpoint" ? false : false);
     }
   }
   // Update Server Stats
@@ -2090,7 +2096,7 @@
   while (isRunning) {
     m_updateLocatorListSema.acquire();
     if (isRunning && !m_connManager.isNetDown()) {
-      (m_locHelper)->updateLocators(this->getServerGroup());
+      (m_locHelper)->updateLocators(getServerGroup());
     }
   }
   LOGFINE("Ending updateLocatorList thread for pool %s", m_poolName.c_str());
@@ -2322,7 +2328,7 @@
       new DataOutput(m_connManager.getCacheImpl()->createDataOutput()));
   TcrMessageReply reply(true, nullptr);
 
-  GfErrType err = this->sendSyncRequest(request, reply);
+  GfErrType err = sendSyncRequest(request, reply);
 
   if (err == GF_NOERR) {
     switch (reply.getMessageType()) {
diff --git a/cppcache/src/ThinClientPoolHADM.cpp b/cppcache/src/ThinClientPoolHADM.cpp
index 244fd2e..4b3685f 100644
--- a/cppcache/src/ThinClientPoolHADM.cpp
+++ b/cppcache/src/ThinClientPoolHADM.cpp
@@ -76,7 +76,7 @@
           "No locators were available during pool initialization with "
           "subscription redundancy.");
     } else {
-      GfErrTypeToException("ThinClientPoolHADM::init", err);
+      throwExceptionIfError("ThinClientPoolHADM::init", err);
     }
   }
 
@@ -266,7 +266,6 @@
       return;
     }
   }
-  GF_DEV_ASSERT("Region not found in ThinClientPoolHADM list" ? false : false);
 }
 
 void ThinClientPoolHADM::readyForEvents() {
diff --git a/cppcache/src/ThinClientRedundancyManager.cpp b/cppcache/src/ThinClientRedundancyManager.cpp
index 75fe357..fbea7c5 100644
--- a/cppcache/src/ThinClientRedundancyManager.cpp
+++ b/cppcache/src/ThinClientRedundancyManager.cpp
@@ -44,6 +44,8 @@
 namespace geode {
 namespace client {
 
+const int MIN_RETRY_ATTEMPTS = 5;
+
 const char* ThinClientRedundancyManager::NC_PerodicACK = "NC PerodicACK";
 
 ThinClientRedundancyManager::ThinClientRedundancyManager(
@@ -399,14 +401,6 @@
   // 3. If primary is connected, m_redundantEndpoints[0] is primary. ( Not
   // checked. To verify, We may have to modify
   //    TcrEndpoint class.)
-
-  GF_DEV_ASSERT(!isRedundancySatisfied || ((m_redundantEndpoints.size() ==
-                                            (size_t)(m_redundancyLevel + 1)) &&
-                                           isPrimaryConnected));
-  GF_DEV_ASSERT(isRedundancySatisfied ||
-                ((int)m_redundantEndpoints.size() <= m_redundancyLevel) ||
-                m_redundancyLevel == -1);
-
   std::shared_ptr<RemoteQueryService> queryServicePtr;
   ThinClientPoolDM* poolDM = dynamic_cast<ThinClientPoolDM*>(m_poolHADM);
   if (poolDM) {
@@ -429,14 +423,6 @@
     }
   }
 
-#if GF_DEVEL_ASSERTS == 1
-  if (isPrimaryConnected && !m_redundantEndpoints[0]->connected()) {
-    LOGWARN(
-        "GF_DEV_ASSERT Warning: Failed condition ( isPrimaryConnected ==> "
-        "m_redundantEndpoints[ 0 ]->connected( ) )");
-  }
-#endif
-
   // Invariants:
   // 1. m_redundantEndpoints UNION m_nonredundantEndpionts = All Endpoints
   // 2. m_redundantEndpoints INTERSECTION m_nonredundantEndpoints = Empty
@@ -444,13 +430,7 @@
   // The global endpoint list does not change ever for HA so getAllEndpoints
   // result or redundantEndpoints/nonredundantEndpoints cannot have stale or
   // deleted endpoints
-  if (!m_poolHADM) {
-    GF_DEV_ASSERT(m_redundantEndpoints.size() +
-                      m_nonredundantEndpoints.size() ==
-                  (unsigned)m_theTcrConnManager->getNumEndPoints());
-  }
 
-  // Update pool stats
   if (m_poolHADM) {
     m_poolHADM->getStats().setSubsServers(
         static_cast<int32_t>(m_redundantEndpoints.size()));
@@ -497,10 +477,6 @@
 void ThinClientRedundancyManager::removeEndpointsInOrder(
     std::vector<TcrEndpoint*>& destVector,
     const std::vector<TcrEndpoint*>& srcVector) {
-#if GF_DEVEL_ASSERTS == 1
-  size_t destInitSize = destVector.size();
-#endif
-
   std::vector<TcrEndpoint*> tempDestVector;
   std::vector<TcrEndpoint*>::iterator itDest;
   std::vector<TcrEndpoint*>::const_iterator itSrc;
@@ -519,23 +495,15 @@
 
   // Postconditions:
   // 1. size of destVector decreases by the size of srcVector
-
-  GF_DEV_ASSERT(destInitSize == destVector.size() + srcVector.size());
 }
 
 void ThinClientRedundancyManager::addEndpointsInOrder(
     std::vector<TcrEndpoint*>& destVector,
     const std::vector<TcrEndpoint*>& srcVector) {
-#if GF_DEVEL_ASSERTS == 1
-  size_t destInitSize = destVector.size();
-#endif
-
   destVector.insert(destVector.end(), srcVector.begin(), srcVector.end());
 
   // Postconditions:
   // 1. Length of destVector increases by the length of srcVector
-
-  GF_DEV_ASSERT(destVector.size() == destInitSize + srcVector.size());
 }
 
 GfErrType ThinClientRedundancyManager::createQueueEP(TcrEndpoint* ep,
@@ -771,7 +739,6 @@
 void ThinClientRedundancyManager::moveEndpointToLast(
     std::vector<TcrEndpoint*>& epVector, TcrEndpoint* targetEp) {
   // Pre-condition
-  GF_DEV_ASSERT(epVector.size() > 0 && targetEp != nullptr);
 
   // Remove Ep
   for (std::vector<TcrEndpoint*>::iterator it = epVector.begin();
@@ -866,9 +833,8 @@
 
   int32_t attempts = static_cast<int32_t>(m_redundantEndpoints.size()) +
                      static_cast<int32_t>(m_nonredundantEndpoints.size());
-  // TODO: FIXME: avoid magic number 5 for retry attempts
-  attempts = attempts < 5
-                 ? 5
+  attempts = attempts < MIN_RETRY_ATTEMPTS
+                 ? MIN_RETRY_ATTEMPTS
                  : attempts;  // at least 5 attempts if ep lists are small.
 
   AuthenticatedView* authenticatedView = nullptr;
@@ -900,7 +866,7 @@
         gua.setAuthenticatedView(authenticatedView);
       }
       err = theHADM->sendRequestToEP(request, reply, primaryEndpoint);
-      if (err == GF_NOERR || err == GF_TIMOUT ||
+      if (err == GF_NOERR || err == GF_TIMEOUT ||
           ThinClientBaseDM::isFatalClientError(err)) {
         break;
       }
@@ -1045,7 +1011,6 @@
             "endpoints, found redundant endpoint.");
       } else if (status == PRIMARY_SERVER) {
         // Primary should be unique
-        GF_DEV_ASSERT(primaryEp == nullptr);
         primaryEp = ep;
         LOGDEBUG(
             "ThinClientRedundancyManager::getAllEndpoints(): sorting "
diff --git a/cppcache/src/ThinClientRegion.cpp b/cppcache/src/ThinClientRegion.cpp
index d812d32..11e2654 100644
--- a/cppcache/src/ThinClientRegion.cpp
+++ b/cppcache/src/ThinClientRegion.cpp
@@ -416,10 +416,10 @@
                                       interestPolicy, receiveValues);
 
   if (m_tcrdm->isFatalError(err)) {
-    GfErrTypeToException("Region::registerKeys", err);
+    throwExceptionIfError("Region::registerKeys", err);
   }
 
-  GfErrTypeToException("Region::registerKeys", err);
+  throwExceptionIfError("Region::registerKeys", err);
 }
 
 void ThinClientRegion::unregisterKeys(
@@ -452,7 +452,7 @@
         "keys vector is empty");
   }
   GfErrType err = unregisterKeysNoThrow(keys);
-  GfErrTypeToException("Region::unregisterKeys", err);
+  throwExceptionIfError("Region::unregisterKeys", err);
 }
 
 void ThinClientRegion::registerAllKeys(bool isDurable, bool getInitialValues,
@@ -504,11 +504,11 @@
                            interestPolicy, receiveValues);
 
   if (m_tcrdm->isFatalError(err)) {
-    GfErrTypeToException("Region::registerAllKeys", err);
+    throwExceptionIfError("Region::registerAllKeys", err);
   }
 
   // Get the entries from the server using a special GET_ALL message
-  GfErrTypeToException("Region::registerAllKeys", err);
+  throwExceptionIfError("Region::registerAllKeys", err);
 }
 
 void ThinClientRegion::registerRegex(const std::string& regex, bool isDurable,
@@ -558,10 +558,10 @@
                            interestPolicy, receiveValues);
 
   if (m_tcrdm->isFatalError(err)) {
-    GfErrTypeToException("Region::registerRegex", err);
+    throwExceptionIfError("Region::registerRegex", err);
   }
 
-  GfErrTypeToException("Region::registerRegex", err);
+  throwExceptionIfError("Region::registerRegex", err);
 }
 
 void ThinClientRegion::unregisterRegex(const std::string& regex) {
@@ -584,7 +584,7 @@
   }
 
   GfErrType err = unregisterRegexNoThrow(regex);
-  GfErrTypeToException("Region::unregisterRegex", err);
+  throwExceptionIfError("Region::unregisterRegex", err);
 }
 
 void ThinClientRegion::unregisterAllKeys() {
@@ -601,7 +601,7 @@
     }
   }
   GfErrType err = unregisterRegexNoThrow(".*");
-  GfErrTypeToException("Region::unregisterAllKeys", err);
+  throwExceptionIfError("Region::unregisterAllKeys", err);
 }
 
 std::shared_ptr<SelectResults> ThinClientRegion::query(
@@ -731,7 +731,7 @@
 
   err = m_tcrdm->sendSyncRequest(request, reply);
 
-  GfErrTypeToException("Region::serverKeys", err);
+  throwExceptionIfError("Region::serverKeys", err);
 
   switch (reply.getMessageType()) {
     case TcrMessage::RESPONSE: {
@@ -754,7 +754,7 @@
       break;
     }
   }
-  GfErrTypeToException("Region::serverKeys", err);
+  throwExceptionIfError("Region::serverKeys", err);
 
   return serverKeys;
 }
@@ -800,7 +800,7 @@
   auto rptr = CacheableBoolean::create(ret);
 
   rptr = std::dynamic_pointer_cast<CacheableBoolean>(handleReplay(err, rptr));
-  GfErrTypeToException("Region::containsKeyOnServer ", err);
+  throwExceptionIfError("Region::containsKeyOnServer ", err);
   return rptr->value();
 }
 
@@ -848,7 +848,7 @@
 
   rptr = std::dynamic_pointer_cast<CacheableBoolean>(handleReplay(err, rptr));
 
-  GfErrTypeToException("Region::containsValueForKey ", err);
+  throwExceptionIfError("Region::containsValueForKey ", err);
   return rptr->value();
 }
 
@@ -856,7 +856,7 @@
     const std::shared_ptr<Serializable>& aCallbackArgument) {
   GfErrType err = GF_NOERR;
   err = localClearNoThrow(aCallbackArgument, CacheEventFlags::NORMAL);
-  if (err != GF_NOERR) GfErrTypeToException("Region::clear", err);
+  if (err != GF_NOERR) throwExceptionIfError("Region::clear", err);
 
   /** @brief Create message and send to bridge server */
 
@@ -865,7 +865,7 @@
                                 std::chrono::milliseconds(-1), m_tcrdm.get());
   TcrMessageReply reply(true, m_tcrdm.get());
   err = m_tcrdm->sendSyncRequest(request, reply);
-  if (err != GF_NOERR) GfErrTypeToException("Region::clear", err);
+  if (err != GF_NOERR) throwExceptionIfError("Region::clear", err);
 
   switch (reply.getMessageType()) {
     case TcrMessage::REPLY:
@@ -892,7 +892,7 @@
     err = invokeCacheListenerForRegionEvent(
         aCallbackArgument, CacheEventFlags::NORMAL, AFTER_REGION_CLEAR);
   }
-  GfErrTypeToException("Region::clear", err);
+  throwExceptionIfError("Region::clear", err);
 }
 
 GfErrType ThinClientRegion::getNoThrow_remote(
@@ -1983,7 +1983,7 @@
   err = m_tcrdm->sendSyncRequest(request, reply);
 
   if (err != GF_NOERR) {
-    GfErrTypeToException("Region::size", err);
+    throwExceptionIfError("Region::size", err);
   }
 
   switch (reply.getMessageType()) {
@@ -2004,7 +2004,7 @@
       err = GF_NOTOBJ;
   }
 
-  GfErrTypeToException("Region::size", err);
+  throwExceptionIfError("Region::size", err);
   return 0;
 }
 
@@ -2881,7 +2881,7 @@
   auto exceptions = std::make_shared<HashMapOfException>();
   auto err = getAllNoThrow_remote(keys, nullptr, exceptions, resultKeys, true,
                                   nullptr);
-  GfErrTypeToException(method, err);
+  throwExceptionIfError(method, err);
   // log any exceptions here
   for (const auto& iter : *exceptions) {
     LOGWARN("%s Exception for key %s:: %s: %s", method,
@@ -2988,7 +2988,7 @@
     }
 
     if (ThinClientBaseDM::isFatalClientError(err)) {
-      GfErrTypeToException("ExecuteOnRegion:", err);
+      throwExceptionIfError("ExecuteOnRegion:", err);
     } else if (err != GF_NOERR) {
       if (err == GF_FUNCTION_EXCEPTION) {
         reExecute = true;
@@ -3009,17 +3009,17 @@
             "%d ",
             attempt);
         if (attempt > retryAttempts) {
-          GfErrTypeToException("ExecuteOnRegion:", err);
+          throwExceptionIfError("ExecuteOnRegion:", err);
         }
         reExecuteForServ = true;
         rc->clearResults();
         failedNodes->clear();
-      } else if (err == GF_TIMOUT) {
+      } else if (err == GF_TIMEOUT) {
         LOGINFO(
             "function timeout. Name: %s, timeout: %d, params: %d, "
             "retryAttempts: %d ",
             func.c_str(), timeout.count(), getResult, retryAttempts);
-        GfErrTypeToException("ExecuteOnRegion", GF_TIMOUT);
+        throwExceptionIfError("ExecuteOnRegion", GF_TIMEOUT);
       } else if (err == GF_CLIENT_WAIT_TIMEOUT ||
                  err == GF_CLIENT_WAIT_TIMEOUT_REFRESH_PRMETADATA) {
         LOGINFO(
@@ -3027,10 +3027,10 @@
             "blacklisted. Name: %s, timeout: %d, params: %d, retryAttempts: "
             "%d ",
             func.c_str(), timeout.count(), getResult, retryAttempts);
-        GfErrTypeToException("ExecuteOnRegion", GF_CLIENT_WAIT_TIMEOUT);
+        throwExceptionIfError("ExecuteOnRegion", GF_CLIENT_WAIT_TIMEOUT);
       } else {
         LOGDEBUG("executeFunction err = %d ", err);
-        GfErrTypeToException("ExecuteOnRegion:", err);
+        throwExceptionIfError("ExecuteOnRegion:", err);
       }
     } else {
       reExecute = false;
@@ -3081,7 +3081,7 @@
     }
 
     if (ThinClientBaseDM::isFatalClientError(err)) {
-      GfErrTypeToException("ExecuteOnRegion:", err);
+      throwExceptionIfError("ExecuteOnRegion:", err);
     } else if (err != GF_NOERR) {
       if (err == GF_FUNCTION_EXCEPTION) {
         reExecute = true;
@@ -3104,17 +3104,17 @@
             "= %d ",
             attempt);
         if (attempt > retryAttempts) {
-          GfErrTypeToException("ExecuteOnRegion:", err);
+          throwExceptionIfError("ExecuteOnRegion:", err);
         }
         reExecute = true;
         rc->clearResults();
         failedNodes->clear();
-      } else if (err == GF_TIMOUT) {
+      } else if (err == GF_TIMEOUT) {
         LOGINFO("function timeout");
-        GfErrTypeToException("ExecuteOnRegion", GF_CACHE_TIMEOUT_EXCEPTION);
+        throwExceptionIfError("ExecuteOnRegion", GF_CACHE_TIMEOUT_EXCEPTION);
       } else {
         LOGDEBUG("reExecuteFunction err = %d ", err);
-        GfErrTypeToException("ExecuteOnRegion:", err);
+        throwExceptionIfError("ExecuteOnRegion:", err);
       }
     }
   } while (reExecute);
@@ -3218,7 +3218,7 @@
   }
 
   if (abortError != GF_NOERR) {
-    GfErrTypeToException("ExecuteOnRegion:", abortError);
+    throwExceptionIfError("ExecuteOnRegion:", abortError);
   }
   return reExecute;
 }
@@ -3282,7 +3282,7 @@
     std::shared_ptr<VersionTag> versionTag) {
   GfErrType err = destroyNoThrowTX(key, aCallbackArgument, -1,
                                    CacheEventFlags::NORMAL, versionTag);
-  GfErrTypeToException("Region::destroyTX", err);
+  throwExceptionIfError("Region::destroyTX", err);
 }
 
 void ThinClientRegion::txInvalidate(
@@ -3291,7 +3291,7 @@
     std::shared_ptr<VersionTag> versionTag) {
   GfErrType err = invalidateNoThrowTX(key, aCallbackArgument, -1,
                                       CacheEventFlags::NORMAL, versionTag);
-  GfErrTypeToException("Region::invalidateTX", err);
+  throwExceptionIfError("Region::invalidateTX", err);
 }
 
 void ThinClientRegion::txPut(
@@ -3306,7 +3306,7 @@
 
   updateStatOpTime(m_regionStats->getStat(), m_regionStats->getPutTimeId(),
                    sampleStartNanos);
-  GfErrTypeToException("Region::putTX", err);
+  throwExceptionIfError("Region::putTX", err);
 }
 
 void ThinClientRegion::setProcessedMarker(bool) {}
diff --git a/cppcache/src/Utils.cpp b/cppcache/src/Utils.cpp
index a832446..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 @@
   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) {
@@ -164,6 +179,12 @@
   return "";
 }
 
+std::string Utils::convertBytesToString(const int8_t* bytes, size_t length,
+                                        size_t maxLength) {
+  return Utils::convertBytesToString(reinterpret_cast<const uint8_t*>(bytes),
+                                     length, maxLength);
+}
+
 int64_t Utils::startStatOpTime() {
   return std::chrono::duration_cast<std::chrono::nanoseconds>(
              std::chrono::steady_clock::now().time_since_epoch())
diff --git a/cppcache/src/Utils.hpp b/cppcache/src/Utils.hpp
index b3577c1..8e6877a 100644
--- a/cppcache/src/Utils.hpp
+++ b/cppcache/src/Utils.hpp
@@ -34,7 +34,6 @@
 #include <geode/internal/geode_base.hpp>
 #include <geode/internal/geode_globals.hpp>
 
-#include "Assert.hpp"
 #include "DistributedSystem.hpp"
 #include "statistics/Statistics.hpp"
 #include "util/Log.hpp"
@@ -142,7 +141,6 @@
           theObject->toString().c_str());
       youHaveBeenWarned = true;
     }
-    GF_DEV_ASSERT(objectSize != 0);
     return objectSize;
   }
 
@@ -167,6 +165,23 @@
                                           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.
+   */
+  static std::string convertBytesToString(const int8_t* bytes, size_t length,
+                                          size_t maxLength = _GF_MSG_LIMIT);
+
+  /**
    * Convert the byte array to a string as "%d %d ...".
    * <code>maxLength</code> as zero implies no limit.
    */
diff --git a/cppcache/src/statistics/AtomicStatisticsImpl.cpp b/cppcache/src/statistics/AtomicStatisticsImpl.cpp
index 3618844..407e436 100644
--- a/cppcache/src/statistics/AtomicStatisticsImpl.cpp
+++ b/cppcache/src/statistics/AtomicStatisticsImpl.cpp
@@ -21,7 +21,6 @@
 
 #include <geode/internal/geode_globals.hpp>
 
-#include "../Assert.hpp"
 #include "StatisticDescriptorImpl.hpp"
 #include "StatisticsTypeImpl.hpp"
 
@@ -68,7 +67,6 @@
     this->uniqueId = uniqueIdArg;
     this->closed = false;
     this->statsType = dynamic_cast<StatisticsTypeImpl*>(typeArg);
-    GF_D_ASSERT(this->statsType != nullptr);
     int32_t intCount = statsType->getIntStatCount();
     int32_t longCount = statsType->getLongStatCount();
     int32_t doubleCount = statsType->getDoubleStatCount();
diff --git a/cppcache/src/statistics/StatArchiveWriter.cpp b/cppcache/src/statistics/StatArchiveWriter.cpp
index a216c06..d3362e7 100644
--- a/cppcache/src/statistics/StatArchiveWriter.cpp
+++ b/cppcache/src/statistics/StatArchiveWriter.cpp
@@ -204,8 +204,6 @@
   bool wroteInstId = false;
   bool checkForChange = true;
   StatisticDescriptor **stats = type->getStats();
-  GF_D_ASSERT(stats != nullptr);
-  GF_D_ASSERT(*stats != nullptr);
   if (resource->isClosed()) {
     return;
   }
diff --git a/cppcache/src/util/exception.hpp b/cppcache/src/util/exception.hpp
index fdebdb4..c148390 100644
--- a/cppcache/src/util/exception.hpp
+++ b/cppcache/src/util/exception.hpp
@@ -33,7 +33,7 @@
 extern void APACHE_GEODE_EXPORT GfErrTypeThrowException(const char* str,
                                                         GfErrType err);
 
-#define GfErrTypeToException(str, err)   \
+#define throwExceptionIfError(str, err)  \
   {                                      \
     if (err != GF_NOERR) {               \
       GfErrTypeThrowException(str, err); \
diff --git a/cppcache/test/CMakeLists.txt b/cppcache/test/CMakeLists.txt
index e9c2c9e..0d3cc0a 100644
--- a/cppcache/test/CMakeLists.txt
+++ b/cppcache/test/CMakeLists.txt
@@ -16,40 +16,9 @@
 cmake_minimum_required( VERSION 3.10 )
 project(apache-geode_unittests LANGUAGES CXX)
 
-add_executable(apache-geode_unittests
-  AutoDeleteTest.cpp
-  ByteArray.cpp
-  ByteArray.hpp
-  ByteArrayFixture.cpp
-  ByteArrayFixture.hpp
-  ByteArrayTest.cpp
-  CacheTest.cpp
-  CacheableKeyCreateTests.cpp
-  CacheableKeysTest.cpp
-  CacheableStringEqualityTest.cpp
-  CacheableStringTests.cpp
-  CacheXmlParserTest.cpp
-  ClientConnectionResponseTest.cpp
-  ClientProxyMembershipIDFactoryTest.cpp
-  DataInputTest.cpp
-  DataOutputTest.cpp
-  ExceptionTypesTest.cpp
-  geodeBannerTest.cpp
-  gtest_extensions.h
-  InterestResultPolicyTest.cpp
-  RegionAttributesFactoryTest.cpp
-  SerializableCreateTests.cpp
-  StructSetTest.cpp
-  TcrMessageTest.cpp
-  CacheableDateTest.cpp
-  util/synchronized_mapTest.cpp
-  util/synchronized_setTest.cpp
-  util/JavaModifiedUtf8Tests.cpp
-  util/functionalTests.cpp
-  util/chrono/durationTest.cpp
-  LocalRegionTest.cpp
-  util/queueTest.cpp
-  ThreadPoolTest.cpp)
+file(GLOB_RECURSE SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp")
+
+add_executable(apache-geode_unittests ${SOURCES})
 
 target_compile_definitions(apache-geode_unittests
   PUBLIC
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 @@
 
 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 @@
                                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 @@
             <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 @@
   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/cppcache/integration/test/ChunkedHeaderTest.cpp b/cppcache/test/ChunkedHeaderTest.cpp
similarity index 100%
rename from cppcache/integration/test/ChunkedHeaderTest.cpp
rename to cppcache/test/ChunkedHeaderTest.cpp
diff --git a/cryptoimpl/CMakeLists.txt b/cryptoimpl/CMakeLists.txt
index 5d4a609..22a3856 100644
--- a/cryptoimpl/CMakeLists.txt
+++ b/cryptoimpl/CMakeLists.txt
@@ -42,7 +42,6 @@
     ACE::ACE_SSL
     _WarningsAsError
   PUBLIC
-    apache-geode
     OpenSSL::Crypto
     OpenSSL::SSL
     c++11
diff --git a/cryptoimpl/DHImpl.cpp b/cryptoimpl/DHImpl.cpp
index 9db49f7..1365d32 100644
--- a/cryptoimpl/DHImpl.cpp
+++ b/cryptoimpl/DHImpl.cpp
@@ -33,8 +33,6 @@
 #include <cstring>
 #include <memory>
 
-#include <geode/internal/geode_globals.hpp>
-
 /*
 static DH * m_dh = nullptr;
 static string m_skAlgo;
diff --git a/cryptoimpl/SSLImpl.cpp b/cryptoimpl/SSLImpl.cpp
index 8616590..b93b766 100644
--- a/cryptoimpl/SSLImpl.cpp
+++ b/cryptoimpl/SSLImpl.cpp
@@ -18,6 +18,7 @@
 #include "SSLImpl.hpp"
 
 #include <cstdint>
+#include <stdexcept>
 
 #include <ace/Guard_T.h>
 
@@ -56,7 +57,9 @@
 
     SSL_CTX_set_cipher_list(sslctx->context(), "DEFAULT");
     sslctx->set_mode(ACE_SSL_Context::SSLv23_client);
-    sslctx->load_trusted_ca(pubkeyfile);
+    if (sslctx->load_trusted_ca(pubkeyfile) != 0) {
+      throw std::invalid_argument("Failed to read SSL trust store.");
+    }
 
     if (strlen(password) > 0) {
       SSL_CTX_set_default_passwd_cb(sslctx->context(), pem_passwd_cb);
@@ -64,8 +67,16 @@
                                              const_cast<char *>(password));
     }
 
-    sslctx->private_key(privkeyfile);
-    sslctx->certificate(privkeyfile);
+    if (sslctx->private_key(privkeyfile) != 0) {
+      throw std::invalid_argument("Invalid SSL keystore password.");
+    }
+    if (sslctx->certificate(privkeyfile) != 0) {
+      throw std::invalid_argument("Failed to read SSL certificate.");
+    }
+    if (::SSL_CTX_use_certificate_chain_file(sslctx->context(), privkeyfile) <=
+        0) {
+      throw std::invalid_argument("Failed to read SSL certificate chain.");
+    }
     SSLImpl::s_initialized = true;
   }
   m_io = new ACE_SSL_SOCK_Stream();
diff --git a/dependencies/ACE/CMakeLists.txt b/dependencies/ACE/CMakeLists.txt
index 3799cf7..010eb7c 100644
--- a/dependencies/ACE/CMakeLists.txt
+++ b/dependencies/ACE/CMakeLists.txt
@@ -13,9 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-project( ACE VERSION 6.5.3 LANGUAGES NONE )
+project( ACE VERSION 6.5.5 LANGUAGES NONE )
 
-set( SHA256 de20bdbfcbcf7d67836e9a2c0875e4eb348a1153e19b83392608330fec3c056a )
+set( SHA256 dc70f1422e5d880b7d2cb59483873acfe6918bb1456c7e36e8b510d9e7769f3b )
 
 if ("SunOS" STREQUAL ${CMAKE_SYSTEM_NAME})
   set( ACE_PLATFORM sunos5_sunc++ )
@@ -162,8 +162,9 @@
   $<BUILD_INTERFACE:${INSTALL_DIR}/include>
 )
 target_compile_definitions(ACE_ACE INTERFACE
-	-D__ACE_INLINE__
-	-DACE_AS_STATIC_LIBS
+  __ACE_INLINE__
+  ACE_AS_STATIC_LIBS
+  __STDC_FORMAT_MACROS # ACE slurps in inttypes.h before cinttypes and clobbers these macros
 )
 target_link_libraries(ACE_ACE INTERFACE
   ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}ACE${CMAKE_STATIC_LIBRARY_SUFFIX}
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 @@
 
 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/benchmark/CMakeLists.txt b/dependencies/benchmark/CMakeLists.txt
index 1a31a0c..63ec1d7 100644
--- a/dependencies/benchmark/CMakeLists.txt
+++ b/dependencies/benchmark/CMakeLists.txt
@@ -13,9 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-project( benchmark VERSION 1.4.1 LANGUAGES NONE )
+project( benchmark VERSION 1.5.0 LANGUAGES NONE )
 
-set( SHA256 61ae07eb5d4a0b02753419eb17a82b7d322786bb36ab62bd3df331a4d47c00a7 )
+set( SHA256 2d22dd3758afee43842bb504af1a8385cccb3ee1f164824e4837c1c1b04d92a0 )
 set( DEPENDS GTest::gtest )
 
 
@@ -63,13 +63,17 @@
   $<BUILD_INTERFACE:${INSTALL_DIR}/include>
 )
 target_link_libraries(benchmark_benchmark INTERFACE
-  ${INSTALL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}benchmark${CMAKE_STATIC_LIBRARY_SUFFIX}
+  ${INSTALL_DIR}/${CMAKE_INSTALL_LIBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}benchmark${CMAKE_STATIC_LIBRARY_SUFFIX}
   Threads::Threads
 )
 if (WIN32)
-target_link_libraries(benchmark_benchmark INTERFACE
-  Shlwapi
-)
+  target_link_libraries(benchmark_benchmark INTERFACE
+    Shlwapi
+  )
+elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+  target_link_libraries(benchmark_benchmark INTERFACE
+    rt
+  )
 elseif (CMAKE_CXX_COMPILER_ID STREQUAL "SunPro")
   target_link_libraries(benchmark_benchmark INTERFACE
     kstat
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/sqlite/CMakeLists.txt b/dependencies/sqlite/CMakeLists.txt
index b26d176..5f4442e 100644
--- a/dependencies/sqlite/CMakeLists.txt
+++ b/dependencies/sqlite/CMakeLists.txt
@@ -13,15 +13,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-project( sqlite VERSION 3260000 LANGUAGES NONE )
+project( sqlite VERSION 3280000 LANGUAGES NONE )
 
-set( SHA256 de5dcab133aa339a4cf9e97c40aa6062570086d6085d8f9ad7bc6ddf8a52096e )
+set( SHA256 d02fc4e95cfef672b45052e221617a050b7f2e20103661cda88387349a9b1327 )
 
 
 set( EXTERN ${PROJECT_NAME}-extern )
 include(ExternalProject)
 ExternalProject_Add( ${EXTERN}
-  URL "https://www.sqlite.org/2018/sqlite-amalgamation-${PROJECT_VERSION}.zip"
+  URL "https://www.sqlite.org/2019/sqlite-amalgamation-${PROJECT_VERSION}.zip"
   URL_HASH SHA256=${SHA256}
   UPDATE_COMMAND ""
   CMAKE_ARGS
diff --git a/dependencies/xerces-c/CMakeLists.txt b/dependencies/xerces-c/CMakeLists.txt
new file mode 100644
index 0000000..b32832b
--- /dev/null
+++ b/dependencies/xerces-c/CMakeLists.txt
@@ -0,0 +1,71 @@
+# 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)
+
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+  set(Xerces_TRANSCODER "-Dtranscoder=iconv")
+endif()
+
+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
+    -Dnetwork:BOOL=OFF
+    ${Xerces_TRANSCODER}
+)
+
+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/dhimpl/DHImpl.hpp b/dhimpl/DHImpl.hpp
index c2b2229..38ba3c8 100644
--- a/dhimpl/DHImpl.hpp
+++ b/dhimpl/DHImpl.hpp
@@ -22,7 +22,6 @@
 
 #include <openssl-compat.h>
 #include <openssl/asn1t.h>
-#include <openssl/dh.h>
 #include <openssl/x509.h>
 
 #include <string>
diff --git a/dist/LICENSE b/dist/LICENSE
index 6772aa9..ef768b8 100644
--- a/dist/LICENSE
+++ b/dist/LICENSE
@@ -290,30 +290,3 @@
 
 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.
diff --git a/docs/geode-native-book/config.yml b/docs/geode-native-book/config.yml
index 6a6ea25..11c8904 100644
--- a/docs/geode-native-book/config.yml
+++ b/docs/geode-native-book/config.yml
@@ -21,15 +21,15 @@
 sections:
 - repository:
     name: geode-native-docs
-  directory: docs/geode-native/19
+  directory: docs/geode-native/110
   subnav_template: geode-nc-nav
 
 template_variables:
   product_name_long: Apache Geode
   product_name: Geode
   product_name_lc: geode
-  product_version: 1.9
-  product_version_nodot: 19
+  product_version: "1.10"
+  product_version_nodot: 110
   client_name: Geode Native
   min_java_update: 121
   support_url: http://geode.apache.org/community
diff --git a/docs/geode-native-book/master_middleman/source/subnavs/geode-nc-nav.erb b/docs/geode-native-book/master_middleman/source/subnavs/geode-nc-nav.erb
index ed5cf39..579c0e3 100644
--- a/docs/geode-native-book/master_middleman/source/subnavs/geode-nc-nav.erb
+++ b/docs/geode-native-book/master_middleman/source/subnavs/geode-nc-nav.erb
@@ -36,6 +36,9 @@
         <li>
           <a href="/docs/geode-native/<%=vars.product_version_nodot%>/getting-started/getting-started-nc-client.html#programming_examples">Programming Examples</a>
         </li>
+        <li>
+          <a href="/docs/geode-native/<%=vars.product_version_nodot%>/getting-started/put-get-example.html">Put/Get/Remove Examples</a>
+        </li>
       </ul>
     </li>
     <li class="has_submenu">
@@ -96,6 +99,9 @@
     <li>
       <a href="/docs/geode-native/<%=vars.product_version_nodot%>/configuring/sysprops.html">System Properties</a>
     </li>
+    <li>
+      <a href="/docs/geode-native/<%=vars.product_version_nodot%>/client-cache-ref.html">Client Cache XML Reference</a>
+    </li>
   </ul>
   </div>
 </div>
diff --git a/docs/geode-native-book/redirects.rb b/docs/geode-native-book/redirects.rb
index c96d075..9b29538 100644
--- a/docs/geode-native-book/redirects.rb
+++ b/docs/geode-native-book/redirects.rb
@@ -15,9 +15,11 @@
 
 # Links to API Documentation #
 r301 %r{/releases/latest/javadoc/(.*)}, 'https://geode.apache.org/releases/latest/javadoc/$1'
+r302 %r{/cppdocs/(.*)}, 'https://geode.apache.org/releases/latest/cppdocs/$1'
+r302 %r{/dotnetdocs/(.*)}, 'https://geode.apache.org/releases/latest/dotnetdocs/$1'
 
 # Links to User Guides #
-rewrite '/', '/docs/geode-native/19/about-client-users-guide.html'
-rewrite '/index.html', '/docs/geode-native/19/about-client-users-guide.html'
-r301 %r{/serverman/(.*)}, 'https://geode.apache.org/docs/guide/19/$1'
-r301 %r{/geodeman/(.*)}, 'https://geode.apache.org/docs/guide/19/$1'
+rewrite '/', '/docs/geode-native/110/about-client-users-guide.html'
+rewrite '/index.html', '/docs/geode-native/110/about-client-users-guide.html'
+r301 %r{/serverman/(.*)}, 'https://geode.apache.org/docs/guide/110/$1'
+r301 %r{/geodeman/(.*)}, 'https://geode.apache.org/docs/guide/110/$1'
diff --git a/docs/geode-native-docs/client-cache-ref.html.md.erb b/docs/geode-native-docs/client-cache-ref.html.md.erb
new file mode 100644
index 0000000..f11c5ef
--- /dev/null
+++ b/docs/geode-native-docs/client-cache-ref.html.md.erb
@@ -0,0 +1,431 @@
+---
+title: Client Cache XML Reference
+---
+
+<!--
+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.
+-->
+
+This section documents the XML elements you can use to configure your <%=vars.product_name%>
+native client application.
+
+To define a configuration using XML:
+
+1. Set cache configuration parameters in a declarative XML file. By convention, this user guide refers to the file as `cache.xml`, but you can choose any name.
+
+1. Specify the filename and path to your XML configuration file by setting the `cache-xml-file`
+property in the `geode.properties` file. If you do not specify path, the application will search for
+the file in its runtime startup directory.
+
+For example:
+
+```
+cache-xml-file=cache.xml
+```
+
+When you run your application, the native client runtime library reads and applies the configuration
+specified in the XML file.
+
+The declarative XML file is used to externalize the configuration of the client cache.
+The contents of the XML file correspond to APIs found in the`apache::geode::client` package for C++ applications,
+and the `Apache::Geode::Client` package for .NET applications.
+
+Elements are defined in the Client Cache XSD file, named `cpp-cache-1.0.xsd`, which you can find in
+your native client distribution in the `xsds` directory, and online at
+`https://geode.apache.org/schema/cpp-cache/cpp-cache-1.0.xsd`.
+
+# Cache Initialization File: XML Essentials
+
+This section assumes you are familiar with XML. When creating a cache initialization file for your
+native client application, keep these basics in mind:
+
+- Place an XML prolog at the top of the file. For example:
+
+    ```xml
+    <?xml version="1.0" encoding="UTF-8"?>
+    ```
+- Quote all parameter values, including numbers and booleans. For example:
+
+    ```xml
+    concurrency-level="10"
+    caching-enabled="true"
+    ```
+
+Some types are specific to the <%=vars.product_name%> cache initialization file:
+
+- **Duration:** Time specified as a non-negative integer and a unit, with no intervening space. The recognized units are `h`, `min`, `s`, `ms`, `us`, and `ns`. For example:
+
+    ```xml
+    idle-timeout = "5555ms"
+    statistic-interval = "10s"
+    update-locator-list-interval="5min"
+    ```
+
+- **Expiration:** Complex type consisting of a duration (integer + unit) and an action, where the action is one of `invalidate`, `destroy`, `local-invalidate`, or `local-destroy`. For example:
+
+    ```xml
+    <expiration-attributes timeout="20s" action="destroy"/>
+    <expiration-attributes timeout="10s" action="invalidate"/>
+    ```
+
+- **Library:** Complex type consisting of a library name and a function name. Used by the client to invoke functions.
+For example:
+
+    ```xml
+    <persistence-manager library-name="SqLiteImpl"
+     library-function-name="createSqLiteInstance">
+    ```
+
+# Cache Initialization File Element Descriptions
+
+This section shows the hierarchy of `<client-cache>` sub-elements that you use to configure <%=vars.product_name%> caches and clients.
+The top-level element in this syntax is `<client-cache>`.
+
+[`<client-cache>`](#client-cache-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<pool>`](#pool-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<locator>`](#locator-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<server>`](#server-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<region>`](#region-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<region-attributes>`](#region-attributes-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<region-time-to-live>`](#region-time-to-live-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<region-idle-time>`](#region-idle-time-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<entry-time-to-live>`](#entry-time-to-live-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<entry-idle-time>`](#entry-idle-time-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<partition-resolver>`](#partition-resolver-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<cache-loader>`](#cache-loader-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<cache-listener>`](#cache-listener-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<cache-writer>`](#cache-writer-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<persistence-manager>`](#persistence-manager-ref)<br/>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[`<pdx>`](#pdx-ref)<br/>
+
+In the descriptions, elements and attributes not designated "required" are optional.
+
+<a id="client-cache-ref"></a>
+## \<client-cache\> Element
+
+The \<client-cache\> element is the top-level element of the XSD file.
+
+Your declarative cache file must include a schema of the following form:
+
+```pre
+<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/cpp-cache-1.0.xsd"
+ version="1.0">
+  ...
+</client-cache>
+```
+
+### Attributes of \<client-cache\>
+
+| Attribute | Description |
+|-----------|-------------|
+| version   | Required. Must be "1.0" |
+
+
+### Sub-elements of \<client-cache\>
+
+`<client-cache>` must contain at least one of these sub-elements:
+
+| Element | Minimum Occurrences | Maximum Occurrences |
+|---------|---------------------|---------------------|
+| <a href="#pool-ref">\<pool\></a> | 0 | unbounded |
+| <a href="#region-ref">\<region\></a> | 0 | unbounded |
+| <a href="#pdx-ref">\<pdx\></a> | 0 | 1 |
+
+<a id="pool-ref"></a>
+## \<pool\> Element
+
+The \<pool\> element is a collection of the connections by which your client application
+communicates with the <%=vars.product_name%> server.
+
+- A connection can specify either a locator or a server.
+- A `<pool>` must contain at least one connection, locator or server, and can contain multiples of either or both.
+
+### Sub-elements of \<pool\>
+
+A `<pool>` must contain at least one sub-element that specifies a connection, which can be either a server or a locator.
+Multiples of either or both types are permitted.
+
+| Element | Minimum Occurrences | Maximum Occurrences |
+|---------|---------------------|---------------------|
+| <a href="#locator-ref">\<locator\></a> | 0 | unbounded |
+| <a href="#server-ref">\<server\></a> | 0 | unbounded |
+
+### Attributes of \<pool\>
+
+| Attribute | Description | Default |
+|-----------|-------------|---------|
+| name      | String. Required. Name of the pool, used when connecting regions to this pool.  |   |
+| free-connection-timeout | Duration.  The amount of time to wait for a free connection if max-connections is set and all of the connections are in use. | 10s |
+| load-conditioning-interval | Duration. The interval at which the pool checks to see if a connection to a given server should be moved to a different server to improve the load balance. | 5min |
+| min-connections | Non-negative integer.  The minimum number of connections to keep available at all times.  When the pool is created, it will create this many connections. If 0 (zero), then connections are not made until an operation is performed that requires client-to-server communication. | 1 |
+| max-connections | Integer >= -1.  The maximum number of connections to be created.  If all of the connections are in use, an operation requiring a client to server connection blocks until a connection is available. A value of -1 means no maximum. | -1 |
+| retry-attempts | Integer >= -1.  The number of times to retry an operation after a timeout or exception.  A value of -1 indicates that a request should be tried against every available server before failing. | -1 |
+| idle-timeout | Duration.  Sets the amount of time a connection can be idle before it expires. A value of 0 (zero) indicates that connections should never expire. | 5s |
+| ping-interval | Duration. The interval at which the pool pings servers. | 10s |
+| read-timeout | Duration. The amount of time to wait for a response from a server before timing out and trying the operation on another server (if any are available). | 10s |
+| server-group | String.  Specifies the name of the server group to which this pool should connect. If the value is null or &#34;&#34; then the pool connects to all servers. | &#34;&#34; |
+| socket-buffer-size | String.  The size in bytes of the socket buffer on each connection established. | 32768 |
+| subscription-enabled | Boolean.  When `true`, establish a server to client subscription. | false |
+| subscription-message-tracking-timeout | String.  The amount of time that messages sent from a server to a client will be tracked. The tracking is done to minimize duplicate events. Entries that have not been modified for this amount of time are expired from the list. | 900s |
+| subscription-ack-interval | String. The amount of time to wait before sending an acknowledgement to the server for events received from server subscriptions. | 100ms |
+| subscription-redundancy | String. Sets the redundancy level for this pool's server-to-client subscriptions.  An effort is made to maintain the requested number of copies (one copy per server) of the server-to-client subscriptions. At most, one copy per server is made up to the requested level. If 0 then no redundant copies are kept on the servers. |  0 |
+| statistic-interval | Duration. The interval at which client statistics are sent to the server. A value of 0 (zero) means do not send statistics. | 0ms (disabled) |
+| pr-single-hop-enabled | String. When `true`, enable single hop optimizations for partitioned regions. | true |
+| thread-local-connections | Boolean. Sets the thread local connections policy for this pool. When `true` then any time a thread goes to use a connection from this pool it will check a thread local cache and see if it already has a connection in it. If so it will use it. If not it will get one from this pool and cache it in the thread local. This gets rid of thread contention for the connections but increases the number of connections the servers see.  When `false` then connections are returned to the pool as soon as the operation being done with the connection completes. This allows connections to be shared among multiple threads keeping the number of connections down. | false |
+| multiuser-authentication | Boolean. Sets the pool to use multi-user secure mode. If in multiuser mode, then app needs to get `RegionService` instance of `Cache`. | false |
+| update-locator-list-interval | Duration. The frequency with which client updates the locator list. To disable this set its value to `std::chrono::milliseconds::zero()`. ||
+
+<a id="locator-ref"></a>
+## \<locator\>
+
+`<locator>` is a sub-element of `<pool>` that defines a connection to a <%=vars.product_name%> locator, specified by a host and port combination.
+
+## Attributes of \<locator\>
+
+| Attribute | Description |
+|-----------|-------------|
+| host      | String. Locator host name. |
+| port      | Integer in the range 0 - 65535, inclusive. Locator port number. |
+
+For example:
+
+```xml
+<locator host="stax01" port="1001" />
+```
+
+<a id="server-ref"></a>
+## \<server\>
+
+`<server>` is a sub-element of `<pool>` that defines a connection to a <%=vars.product_name%> server, specified by a host and port combination.
+
+## Attributes of \<server\>
+
+| Attribute | Description |
+|-----------|-------------|
+| host      | String. Server host name. |
+| port      | Integer in the range 0 - 65535, inclusive. Server port number. |
+
+For example:
+
+```xml
+<server host="motown01" port="2001" />
+```
+
+<a id="region-ref"></a>
+## \<region\>
+
+You can specify 0 or more regions per `<client-cache>`. There is no maximum limit on the number of regions a `<client-cache>` can contain.
+
+In order to connect to a <%=vars.product_name%> server, a client application must define at least one region 
+whose name corresponds to that of a region on the server.
+
+Regions can be nested.
+
+### Sub-elements of \<region\>
+
+Use the `<region-attributes>` sub-element to specify most of the characteristics of a region. Regions may be nested.
+
+| Element | Minimum Occurrences | Maximum Occurrences |
+|---------|---------------------|---------------------|
+| <a href="#region-attributes-ref">\<region-attributes\></a> | 0 | 1 |
+| \<region\> | 0 | unbounded |
+
+### Attributes of \<region\>
+
+You can specify many attributes to configure a region, but most of these attributes are encapsulated in the <a href="#region-attributes-ref">`<region-attributes>`</a> sub-element.
+The `<region>` element itself has only two attributes: a required name and an optional reference identifier.
+
+| Attribute | Description |
+|-----------|-------------|
+| name | String. Required. |
+| refid |  String. |
+
+<a id="region-attributes-ref"></a>
+## \<region-attributes\>
+
+Specify 0 or 1 `<region-attributes>` element for each `<region>` you define.
+
+If you specify a `<region-attributes>` element, you must specify at least one of these
+sub-elements. When more than one sub-element is specified, they must be defined in this order:
+
+| Element | Type | Minimum Occurrences | Maximum Occurrences |
+|---------|------|---------------------|---------------------|
+| [\<region-time-to-live\>](#region-time-to-live-ref) | expiration | 0 | 1 |
+| [\<region-idle-time\>](#region-idle-time-ref) | expiration | 0 | 1 |
+| [\<entry-time-to-live\>](#entry-time-to-live-ref) | expiration | 0 | 1 |
+| [\<entry-idle-time\>](#entry-idle-time-ref) | expiration | 0 | 1 |
+| [\<partition-resolver\>](#partition-resolver-ref) | library | 0 | 1 |
+| [\<cache-loader\>](#cache-loader-ref)  | library | 0 | 1 |
+| [\<cache-listener\>](#cache-listener-ref)  | library | 0 | 1 |
+| [\<cache-writer\>](#cache-writer-ref)  | library | 0 | 1 |
+| [\<persistence-manager\>](#persistence-manager-ref) | list of properties | 0 | 1 |
+
+### Attributes of \<region-attributes\>
+
+| Attribute | Description | Default |
+|-----------|-------------|---------|
+| caching-enabled | Boolean. If true, cache data for this region in this process. If false, then no data is stored in the local process, but events and distributions will still occur, and the region can still be used to put and remove, etc. | true |
+| cloning-enabled | Boolean. Sets cloning on region. | false |
+| scope | Enumeration: `local`, `distributed-no-ack`, `distributed-ack` | |
+| initial-capacity | String. Sets the initial entry capacity for the region. | 10000 |
+| load-factor | String. Sets the entry load factor for the next `RegionAttributes` to be created. | 0.75 |
+| concurrency-level | String. Sets the concurrency level of the next `RegionAttributes` to be created. | 16 |
+| lru-entries-limit | String. Sets the maximum number of entries this cache will hold before using LRU eviction. A return value of zero, 0, indicates no limit. If disk-policy is `overflows`, must be greater than zero. | |
+| disk-policy | Enumeration: `none`, `overflows`, `persist`. Sets the disk policy for this region. | none |
+| endpoints | String. A list of `servername:port-number` pairs separated by commas. | |
+| client-notification | Boolean true/false (on/off) | false |
+| pool-name | String. The name of the pool to attach to this region. The pool with the specified name must already exist. | |
+| concurrency-checks-enabled | Boolean: true/false. Enables concurrent modification checks. | true |
+| id | String. | |
+| refid | String. | |
+
+<a id="region-time-to-live-ref"></a>
+## \<region-time-to-live\>
+
+\<region-time-to-live\> specifies how long this region remains in the cache after the last create or update, and the expiration action to invoke when time runs out.
+A create or update operation on any entry in the region resets the region's counter, as well. Get (read) operations do not reset the counter.
+
+Use the `<expiration-attributes>` sub-element to specify duration and expiration action.
+<a id="expiration-attributes-ref"></a>
+The attributes of \<expiration-attributes\> must be defined in this order:
+
+| Attribute | Description |
+|-----------|-------------|
+| timeout |  Duration, specified as an integer and units. Required. |
+| action | Enumeration. One of: `invalidate`, `destroy`, `local-invalidate`, `local-destroy` |
+
+<a id="region-idle-time-ref"></a>
+## \<region-idle-time\>
+
+\<region-idle-time\> specifies how long this region remains in the cache after the last access, and the expiration action to invoke when time runs out.
+The counter is reset after any access, including create, put, and get operations. Access to any entry in the region resets the region's counter, as well.
+
+Use the `<expiration-attributes>` sub-element to specify duration and expiration action. The attributes of \<expiration-attributes\> must be defined in this order:
+
+| Attribute | Description |
+|-----------|-------------|
+| timeout |  Duration, specified as an integer and units. Required. |
+| action | Enumeration. One of: `invalidate`, `destroy`, `local-invalidate`, `local-destroy` |
+
+<a id="entry-time-to-live-ref"></a>
+## \<entry-time-to-live\>
+
+\<entry-time-to-live\> specifies how long this entry remains in the cache after the last create or update, and the expiration action to invoke when time runs out.
+Get (read) operations do not reset the counter.
+
+Use the `<expiration-attributes>` sub-element to specify duration and expiration action. The attributes of \<expiration-attributes\> must be defined in this order:
+
+| Attribute | Description |
+|-----------|-------------|
+| timeout |  Duration, specified as an integer and units. Required. |
+| action | Enumeration. One of: `invalidate`, `destroy`, `local-invalidate`, `local-destroy` |
+
+<a id="entry-idle-time-ref"></a>
+## \<entry-idle-time\>
+
+\<entry-idle-time\> specifies how long this entry remains in the cache after the last access, and the expiration action to invoke when time runs out.
+The counter is reset after any access, including create, put, and get operations. 
+
+Use the `<expiration-attributes>` sub-element to specify duration and expiration action. The attributes of \<expiration-attributes\> must be defined in this order:
+
+| Attribute | Description |
+|-----------|-------------|
+| timeout |  Duration, specified as an integer and units. Required. |
+| action | Enumeration. One of: `invalidate`, `destroy`, `local-invalidate`, `local-destroy` |
+
+<a id="partition-resolver-ref"></a>
+## \<partition-resolver\>
+
+\<partition-resolver\> identifies a function by specifying `library-name` and `library-function-name`.
+
+A partition resolver is used for single-hop access to partitioned region entries on the server side. This resolver
+implementation must match that of the `PartitionResolver` on the server side.
+See the [API Class Reference](/cppdocs/hierarchy.html) for the **PartitionResolver** class.
+
+For example:
+
+```xml
+<partition-resolver library-name="appl-lib"
+ library-function-name="createTradeKeyResolver"/>
+```
+
+<a id="cache-loader-ref"></a>
+## \<cache-loader\>
+
+\<cache-loader\> identifies a cache loader function by specifying `library-name` and `library-function-name`.
+See the [API Class Reference](/cppdocs/hierarchy.html) for the **CacheLoader** class.
+
+<a id="cache-listener-ref"></a>
+## \<cache-listener\>
+
+\<cache-listener\> identifies a cache listener function by specifying `library-name` and `library-function-name`.
+See the [API Class Reference](/cppdocs/hierarchy.html) for the **CacheListener** class.
+
+<a id="cache-writer-ref"></a>
+## \<cache-writer\>
+
+\<cache-writer\> identifies a cache writer function by specifying `library-name` and `library-function-name`.
+See the [API Class Reference](/cppdocs/hierarchy.html) for the **CacheWriter** class.
+
+<a id="persistence-manager-ref"></a>
+## \<persistence-manager\>
+
+For each region, if the disk-policy attribute is set to `overflows`, a persistence-manager plug-in
+must perform cache-to-disk and disk-to-cache operations.
+See the [API Class Reference](/cppdocs/hierarchy.html) for the **PersistenceManager** class.
+
+\<persistence-manager\> identifies a persistence manager function by specifying `library-name` and `library-function-name`.
+You can also specify a set of properties to be passed to the function as parameters.
+
+The sub-element `<properties>` is a sequence of 0 or more `<property>` elements.
+
+Each `<property>` is a name-value pair. Where the attributes must be specified in this order: 
+
+- `name`
+-  `value`
+
+For example:
+
+```xml
+<region-attributes>
+   <persistence-manager library-name="libSqLiteImpl.so" library-function-name="createSqLiteInstance">
+      <properties>
+         <property name="PersistenceDirectory" value="/xyz"/>
+         <property name="PageSize" value="65536"/>
+         <property name="MaxPageCount" value="1073741823"/>
+      </properties>
+   </persistence-manager>
+</region-attributes>
+```
+
+<a id="pdx-ref"></a>
+## \<pdx\>
+
+Specifies the configuration for the Portable Data eXchange (PDX) method of serialization.
+
+### Attributes of \<pdx\>
+
+| Attribute | Description |
+|-----------|-------------|
+| ignore-unread-fields |  Boolean. When `true`, do not preserve unread PDX fields during deserialization. You can use this option to save memory. Set this attribute to `true` only in members that are only reading data from the cache. |
+| read-serialized | Boolean. When `true`, PDX deserialization produces a `PdxInstance` instead of an instance of the domain class. |
+
+
+
diff --git a/docs/geode-native-docs/configuring/configuration.html.md.erb b/docs/geode-native-docs/configuring/configuration.html.md.erb
index e421970..7db11a1 100644
--- a/docs/geode-native-docs/configuring/configuration.html.md.erb
+++ b/docs/geode-native-docs/configuring/configuration.html.md.erb
@@ -22,13 +22,19 @@
 You can configure your native client application:
 
  - Programmatically in your app code
- - Via XML files and properties files
+ - Via XML files and properties files (see [Client Cache XML Reference](../client-cache-ref.html))
  - Through a combination of programmatic and file-based approaches
 
 This section describes configuration on two levels, the system level and the cache level.
+System property settings describe your application's behavior, while cache configuration describes data.
 
 ## <a id="config_programmatic_vs_xml"></a>Programmatic Configuration vs XML Configuration
 
+Programmatic configuration enables your client application to dynamically adapt to changing runtime conditions.
+
+In contrast, XML configuration externalizes properties, such as locator addresses and pool
+connection details, so they can be changed without requiring that you recompile your application.
+
 **C++ RegionFactory Example**
 
 The following examples illustrate how to set a region's expiration timeout attribute programmatically and through XML.
diff --git a/docs/geode-native-docs/configuring/sysprops.html.md.erb b/docs/geode-native-docs/configuring/sysprops.html.md.erb
index 891dea6..081ec6a 100644
--- a/docs/geode-native-docs/configuring/sysprops.html.md.erb
+++ b/docs/geode-native-docs/configuring/sysprops.html.md.erb
@@ -197,12 +197,12 @@
 </tr>
 <tr class="odd">
 <td>archive-disk-space-limit</td>
-<td>Maximum amount of disk space, in megabytes, allowed for all archive files, current, and rolled. If set to 0, the space is unlimited.</td>
+<td>Maximum amount of disk space, in gigabytes, allowed for all archive files, current, and rolled. If set to 0, the space is unlimited.</td>
 <td>0</td>
 </tr>
 <tr class="even">
 <td>archive-file-size-limit</td>
-<td>Maximum size, in bytes, of a single statistic archive file. Once this limit is exceeded, a new statistic archive file is created and the current archive file becomes inactive. If set to 0, the file size is unlimited.</td>
+<td>Maximum size, in megabytes, of a single statistic archive file. Once this limit is exceeded, a new statistic archive file is created and the current archive file becomes inactive. If set to 0, the file size is unlimited.</td>
 <td>0</td>
 </tr>
 <tr class="odd">
diff --git a/docs/geode-native-docs/examples.html.md.erb b/docs/geode-native-docs/examples.html.md.erb
deleted file mode 100644
index 420c390..0000000
--- a/docs/geode-native-docs/examples.html.md.erb
+++ /dev/null
@@ -1,34 +0,0 @@
----
-title:  Programming Examples
----
-
-The <%=vars.product_name%> Client build provides a set of programming examples to help you understand the client API.
-The `examples` directory contains CMake files and a `cpp` subdirectory containing C++ examples.
-The Windows build also includes a `dotnet` subdirectory containing C# examples.
-
-CMake files are located at each level of the directory structure to allow examples to be built individually or in groups.
-
-The directory structure resembles this hierarchy (some entries are omitted for clarity):
-
-    MyProject/
-      cmake/
-      CMakeLists.txt
-      examples/
-        BUILDING.md
-        CMakeLists.txt
-        CMakeLists.txt.in
-        cmake/
-        cpp/
-          BUILDING.md
-          customserializable/
-          customserializer/
-          put-get-remove/
-        dotnet/
-          AuthInitialize/
-          PdxAutoSerializer/
-          PutGetRemove/
-          README.md
-
-See the `BUILDING.md` or `README.md` file in each directory for detailed instructions on building
-and executing the examples, and read the source code to understand how the examples are constructed.
-
diff --git a/docs/geode-native-docs/getting-started/getting-started-nc-client.html.md.erb b/docs/geode-native-docs/getting-started/getting-started-nc-client.html.md.erb
index aeed8f9..647612c 100644
--- a/docs/geode-native-docs/getting-started/getting-started-nc-client.html.md.erb
+++ b/docs/geode-native-docs/getting-started/getting-started-nc-client.html.md.erb
@@ -120,38 +120,41 @@
 
 The directory structure resembles this hierarchy (some entries are omitted for clarity):
 
-    ```
-    MyProject/
-      cmake/
-      CMakeLists.txt
-      examples/
-        BUILD-EXAMPLES.md
-        CMakeLists.txt
-        CMakeLists.txt.in
-        cmake/
-        cpp/
-          authinitialize/
-          continuousquery/
-          dataserializable/
-          functionexecution/
-          pdxserializable/
-          pdxserializer/
-          putgetremove/
-          remotequery/
-          sslputget/
-          transaction/
-        dotnet/
-          authinitialize/
-          continuousquery/
-          dataserializable/
-          functionexecution/
-          pdxautoserializer/
-          pdxserializable/
-          putgetremove/
-          remotequery/
-          sslputget/
-          transaction/
-    ```
+```
+MyProject/
+  cmake/
+  CMakeLists.txt
+  examples/
+    BUILD-EXAMPLES.md
+    CMakeLists.txt
+    CMakeLists.txt.in
+    cmake/
+    cpp/
+      authinitialize/
+      continuousquery/
+      dataserializable/
+      functionexecution/
+      pdxserializable/
+      pdxserializer/
+      putgetremove/
+      remotequery/
+      sslputget/
+      transaction/
+    dotnet/
+      authinitialize/
+      continuousquery/
+      dataserializable/
+      functionexecution/
+      pdxautoserializer/
+      pdxserializable/
+      putgetremove/
+      remotequery/
+      sslputget/
+      transaction/
+```
 
 See the `BUILD-EXAMPLES.md` file for detailed instructions on building and executing the examples,
 and read the source code to understand how the examples are constructed.
+
+See [Put/Get/Remove Examples](put-get-example.html) for sample code showing the basics of how a client application
+connects to a <%=vars.product_name%> cluster and performs basic operations on a remote server.
diff --git a/docs/geode-native-docs/getting-started/put-get-example.html.md.erb b/docs/geode-native-docs/getting-started/put-get-example.html.md.erb
new file mode 100644
index 0000000..586fd29
--- /dev/null
+++ b/docs/geode-native-docs/getting-started/put-get-example.html.md.erb
@@ -0,0 +1,129 @@
+---
+title:  Put/Get/Remove Examples
+---
+
+<!--
+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.
+-->
+
+The native client release contains examples, written for .NET and C++, showing how a client application
+can establish a connection to a cluster and then use that connection to perform basic operations on a remote server. 
+The examples are located in `../examples/dotnet/putgetremove` and `../examples/cpp/putgetremove`, respectively. 
+
+Both examples perform the same sequence of operations, displaying simple log entries as they run.
+
+- To run an example, follow the instructions in the `README.md` file in the example directory.
+- Review the source code in the example directory to see exactly how it operates.
+
+- Begin by running a script that sets up the server-side environment by invoking `gfsh` commands to create a region, simply called "example_userinfo."
+
+- Run the example client application, which performs the following steps:
+
+  - Connects to the server
+  - Performs region put operations using key/value pairs
+  - Uses region get to retrieve the values
+  - Uses region remove to remove the values
+
+### .NET Example
+
+This section contains code snippets showing highlights of the .NET put/get/remove example. They are not intended for cut-and-paste execution.
+For the complete source, see the example source directory.
+
+The .NET example creates a cache, then uses it to create a connection pool and a region object (of class `IRegion`).
+
+```csharp
+   var cacheFactory = new CacheFactory()
+       .Set("log-level", "none");
+   var cache = cacheFactory.Create();
+
+   var poolFactory = cache.GetPoolFactory()
+       .AddLocator("localhost", 10334);
+   poolFactory.Create("pool");
+
+   var regionFactory = cache.CreateRegionFactory(RegionShortcut.PROXY)
+       .SetPoolName("pool");
+   var region = regionFactory.Create<string, string("example_userinfo");
+```
+
+After declaring some keys and values, the client then populates the data store with two key/value pairs. 
+
+```csharp
+      region.Put(rtimmonsKey, rtimmonsValue);
+      region.Put(scharlesKey, scharlesValue);
+```
+
+Next, the application retrieves the stored values using `Get` operations.
+
+```csharp
+      var user1 = region.Get(rtimmonsKey, null);
+      var user2 = region.Get(scharlesKey, null);
+```
+
+Finally, the application deletes one of the stored values using the `Remove` method.
+
+```csharp
+      if (region.Remove(rtimmonsKey))
+      {
+        Console.WriteLine("Info for " + rtimmonsKey + " has been deleted");
+      }
+      else
+      {
+        Console.WriteLine("Info for " + rtimmonsKey + " has not been deleted");
+      }
+```
+
+### C++ Example
+
+This section contains code snippets showing highlights of the C++ put/get/remove example. They are not intended for cut-and-paste execution.
+For the complete source, see the example source directory.
+
+The C++ example creates a cache, then uses it to create a connection pool and a region object (of class `Region`).
+
+```cpp
+  auto cacheFactory = CacheFactory();
+  cacheFactory.set("log-level", "none");
+  auto cache = cacheFactory.create();
+  auto poolFactory = cache.getPoolManager().createFactory();
+
+  poolFactory.addLocator("localhost", 10334);
+  auto pool = poolFactory.create("pool");
+  auto regionFactory = cache.createRegionFactory(RegionShortcut::PROXY);
+  auto region = regionFactory.setPoolName("pool").create("example_userinfo");
+```
+
+The client then populates the data store with two key/value pairs. 
+
+```cpp
+  region->put("rtimmons", "Robert Timmons");
+  region->put("scharles", "Sylvia Charles");
+```
+
+Next, the application retrieves the stored values using `Get` operations.
+
+```cpp
+  auto user1 = region->get("rtimmons");
+  auto user2 = region->get("scharles");
+```
+
+Finally, the application deletes one of the stored values using the `Remove` method.
+
+```cpp
+  if (region->existsValue("rtimmons")) {
+    std::cout << "rtimmons's info not deleted" << std::endl;
+  } else {
+    std::cout << "rtimmons's info successfully deleted" << std::endl;
+  }
+```
diff --git a/docs/geode-native-docs/serialization/data-serialization.html.md.erb b/docs/geode-native-docs/serialization/data-serialization.html.md.erb
index 6ed5a60..41643f7 100644
--- a/docs/geode-native-docs/serialization/data-serialization.html.md.erb
+++ b/docs/geode-native-docs/serialization/data-serialization.html.md.erb
@@ -27,3 +27,277 @@
 
 To learn more about other serialization options, see the [Data Serialization section in the _<%=vars.product_name_long%> User Guide_](serverman/developing/data_serialization/chapter_overview.html).
 
+<a id="implementing_pdxsbl_class"></a>
+## Implementing a PdxSerializable Custom Class
+
+PdxSerializable provides custom serialization to an individual class. Fields within an object can be serialized separately from the rest of the class.
+
+The type of serialization and its implementation can be specified entirely in the client
+application, with no need to create corresponding code on the <%=product_name%> server.
+
+<a id="setup_pdxsbl_class"></a>
+### Setup
+
+PdxSerializable provides custom serialization to an individual class. Fields within an object can be serialized separately from the rest of the class.
+
+Setting up a custom class for PdxSerializable treatment requires some preparatory steps:
+
+- The custom class must inherit from the .NET IPdxSerializable interface or the C++ PdxSerializable interface.
+
+- You must provide serialization instructions for objects of the custom class. Specifically:
+
+  -  You must implement the `ToData()` and `FromData()` methods for .NET applications, or the `toData()` and
+  `fromData()` methods in C++ applications.
+  -  You must provide a "factory method" that returns an instance of the custom object.
+
+- Your application must register your custom class with the cache, which takes care of informing the server of your
+  serialization scheme. With registration, you provide the name of the "factory method" you created for instantiating
+  objects of the custom class.
+
+<a id="pdxsbl_examples"></a>
+## PdxSerializable Examples
+
+The native client release contains examples, written for .NET and C++, showing how a client application
+can register for serialization of custom objects using the .NET IPdxSerializable interface or the C++ PdxSerializable interface.
+
+The examples are located in `examples\dotnet\pdxserializable` and `examples/cpp/pdxserializable`, respectively. 
+
+The examples define the serializable class, `Orders`, including its serialization and deserialization methods and its factory method.
+Once these pieces are in place, execution is simple: the main routine of the example registers the serializable class then performs some put and get operations.
+
+<a id="pdxsbl_execution"></a>
+### Execution
+
+Both examples perform the same sequence of operations, displaying simple log entries as they run.
+
+- To run an example, follow the instructions in the README.md file in the example directory.
+- Review the source code in the example directory to see exactly how it operates.
+
+- Begin by running a script that sets up the server-side environment by invoking `gfsh` commands to create a region, a locator, and a server.
+
+- Run the example client application, which performs the following steps:
+
+  - Connects to the server
+  - Registers the PdxSerializable class
+  - Creates orders
+  - Stores orders
+  - Retrieves orders
+
+
+<a id="pdsxbl_dotnet_example"></a>
+### .NET Example
+
+This section contains code snippets showing highlights of the .NET PdxSerializable example. They are not intended for cut-and-paste execution.
+For the complete source, see the example source directory.
+
+The .NET example defines a PdxSerializable class called `Order` that inherits from the `IPdxSerializable` interface.
+An `Order` object contains three fields:
+
+- an integer `order_id`
+- a string `name`
+- a short-int `quantity`
+
+From Order.cs:
+
+```csharp
+  public class Order : IPdxSerializable
+  {
+    ...
+    public long OrderId { get; set; }
+    public string Name { get; set; }
+    public short Quantity { get; set; }
+```
+
+Using the `IPdxSerializable` read and write methods, the `Order` class defines `ToData()` and `FromData()`
+methods that perform the serialization and deserialization operations, respectively, and the `CreateDeserializable()` factory method:
+
+From Order.cs:
+
+```csharp
+    public void ToData(IPdxWriter output)
+    {
+      output.WriteLong(ORDER_ID_KEY_, OrderId);
+      output.MarkIdentityField(ORDER_ID_KEY_);
+
+      output.WriteString(NAME_KEY_, Name);
+      output.MarkIdentityField(NAME_KEY_);
+
+      output.WriteInt(QUANTITY_KEY_, Quantity);
+      output.MarkIdentityField(QUANTITY_KEY_);
+    }
+
+    public void FromData(IPdxReader input)
+    {
+      OrderId = input.ReadLong(ORDER_ID_KEY_);
+      Name = input.ReadString(NAME_KEY_);
+      Quantity = (short)input.ReadInt(QUANTITY_KEY_);
+    }
+
+    public static IPdxSerializable CreateDeserializable()
+    {
+      return new Order();
+    }
+```
+
+The .NET example mainline creates a cache, then uses it to register the PdxSerializable class that was created in Orders.cs:
+
+```csharp
+   var cacheFactory = new CacheFactory()
+       .Set("log-level", "none");
+   var cache = cacheFactory.Create();
+
+   cache.TypeRegistry.RegisterPdxType(Order.CreateDeserializable);
+```
+
+The client creates a connection pool and a region named "example_orderobject":
+
+```csharp
+   var poolFactory = cache.GetPoolFactory()
+       .AddLocator("localhost", 10334);
+   poolFactory.Create("pool");
+
+   var regionFactory = cache.CreateRegionFactory(RegionShortcut.PROXY)
+        .SetPoolName("pool");
+   var orderRegion = regionFactory.Create<int, Order>("example_orderobject");
+```
+
+After declaring some keys and values, the client then stores and retrieves an `Order` object:
+
+```csharp
+    const int orderKey = 65;
+
+    var order = new Order(orderKey, "Donuts", 12);
+
+    Console.WriteLine("order to put is " + order);
+    orderRegion.Put(orderKey, order, null);
+
+    Console.WriteLine("Successfully put order, getting now...");
+    var orderRetrieved = orderRegion.Get(orderKey, null);
+
+    Console.WriteLine("Order key: " + orderKey + " = " + orderRetrieved);
+```
+
+Finally, the application closes the cache:
+
+```csharp
+    cache.Close();
+```
+
+<a id="pdxsbl_cpp_example"></a>
+### C++ Example
+
+This section contains code snippets showing highlights of the C++ PdxSerialiable example. They are not intended for cut-and-paste execution.
+For the complete source, see the example source directory.
+
+The C++ example defines a PdxSerializable class called `Order` that inherits from the `PdxSerializable` interface.
+An `Order` object contains three fields:
+
+- an integer `order_id`
+- a string `name`
+- a short-int `quantity`
+
+From Order.hpp:
+
+```cpp
+class Order : public PdxSerializable {
+ public:
+ ...
+
+ private:
+  int32_t order_id_;
+  std::string name_;
+  int16_t quantity_;
+};
+
+```
+
+Using the PdxSerializable read and write methods, the `Order` class defines `fromData()` and `toData()`
+methods that perform the deserialization and serialization operations, respectively, and the
+`createDeserializable()` factory method:
+
+From Order.cpp:
+
+```cpp
+void Order::fromData(PdxReader& pdxReader) {
+  order_id_ = pdxReader.readInt(ORDER_ID_KEY_);
+  name_ = pdxReader.readString(NAME_KEY_);
+  quantity_ = pdxReader.readShort(QUANTITY_KEY_);
+}
+
+void Order::toData(PdxWriter& pdxWriter) const {
+  pdxWriter.writeInt(ORDER_ID_KEY_, order_id_);
+  pdxWriter.markIdentityField(ORDER_ID_KEY_);
+
+  pdxWriter.writeString(NAME_KEY_, name_);
+  pdxWriter.markIdentityField(NAME_KEY_);
+
+  pdxWriter.writeShort(QUANTITY_KEY_, quantity_);
+  pdxWriter.markIdentityField(QUANTITY_KEY_);
+}
+
+...
+
+std::shared_ptr<PdxSerializable> Order::createDeserializable() {
+  return std::make_shared<Order>();
+}
+```
+
+The C++ example mainline creates a cache, then uses it to create a connection pool and a region object (of class `Region`).
+
+```cpp
+  auto cacheFactory = CacheFactory();
+  cacheFactory.set("log-level", "none");
+  auto cache = cacheFactory.create();
+  auto poolFactory = cache.getPoolManager().createFactory();
+
+  poolFactory.addLocator("localhost", 10334);
+  auto pool = poolFactory.create("pool");
+  auto regionFactory = cache.createRegionFactory(RegionShortcut::PROXY);
+  auto region = regionFactory.setPoolName("pool").create("custom_orders");
+```
+
+The client registers the PdxSerializable class that was created in Orders.cpp:
+
+```cpp
+  cache.getTypeRegistry().registerPdxType(Order::createDeserializable);
+```
+
+The client then instantiates and stores two `Order` objects:
+
+```cpp
+  auto order1 = std::make_shared<Order>(1, "product x", 23);
+  auto order2 = std::make_shared<Order>(2, "product y", 37);
+
+  region->put("Customer1", order1);
+  region->put("Customer2", order2);
+```
+
+Next, the application retrieves the stored values, in one case extracting the fields defined in
+the serialization code:
+
+```cpp
+  if (auto order1retrieved =
+          std::dynamic_pointer_cast<Order>(region->get("Customer1"))) {
+    std::cout << "OrderID: " << order1retrieved->getOrderId() << std::endl;
+    std::cout << "Product Name: " << order1retrieved->getName() << std::endl;
+    std::cout << "Quantity: " << order1retrieved->getQuantity() << std::endl;
+  } else {
+    std::cout << "Order 1 not found." << std::endl;
+  }
+```
+
+The application retrieves the second object and displays it without extracting the separate fields:
+
+```cpp
+  if (region->existsValue("rtimmons")) {
+    std::cout << "rtimmons's info not deleted" << std::endl;
+  } else {
+    std::cout << "rtimmons's info successfully deleted" << std::endl;
+  }
+```
+
+Finally, the application closes the cache:
+
+```cpp
+  cache.close();
+```
diff --git a/docs/geode-native-docs/transactions.html.md.erb b/docs/geode-native-docs/transactions.html.md.erb
index 3b06112..9ae445b 100644
--- a/docs/geode-native-docs/transactions.html.md.erb
+++ b/docs/geode-native-docs/transactions.html.md.erb
@@ -69,7 +69,7 @@
 - To run an example, follow the instructions in the `README.md` file in the example directory.
 - Review the source code in the example directory to see exactly how it operates.
 
-- You begin by running a script that sets up the servers-side environment by invoking `gfsh` commands to create a region, simply called "exampleRegion".
+- You begin by running a script that sets up the server-side environment by invoking `gfsh` commands to create a region, simply called "exampleRegion."
 
 - You run the example client application, which performs the following steps:
 
diff --git a/examples/dotnet/putgetremove/Program.cs b/examples/dotnet/putgetremove/Program.cs
index 8bbe9f1..084cc02 100644
--- a/examples/dotnet/putgetremove/Program.cs
+++ b/examples/dotnet/putgetremove/Program.cs
@@ -43,8 +43,8 @@
       const string scharlesKey = "scharles";
       const string scharlesValue = "Sylvia Charles";
 
-      region.Put(rtimmonsKey, rtimmonsValue, null);
-      region.Put(scharlesKey, scharlesValue, null);
+      region.Put(rtimmonsKey, rtimmonsValue);
+      region.Put(scharlesKey, scharlesValue);
 
       Console.WriteLine("Getting the user info from the region");
       var user1 = region.Get(rtimmonsKey, null);
diff --git a/packer/build-linux.json b/packer/build-linux.json
index 4adbae0..7b47588 100644
--- a/packer/build-linux.json
+++ b/packer/build-linux.json
@@ -1,8 +1,8 @@
 {
   "variables":{
     "region":"us-west-2",
-    "source_ami":"ami-1e41877e",
-    "source_image_name":"X.vmx",
+    "source_ami":"",
+    "source_image_name":"",
     "image_name":"build-linux"
   },
   "builders":[
@@ -94,8 +94,7 @@
       "type":"shell",
       "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
       "scripts":[
-        "rhel/cleanup.sh",
-        "rhel/zerodisk.sh"
+        "rhel/cleanup.sh"
       ]
     }
   ]
diff --git a/packer/build-rhel-6.json b/packer/build-rhel-6.json
new file mode 100644
index 0000000..cbd6004
--- /dev/null
+++ b/packer/build-rhel-6.json
@@ -0,0 +1,94 @@
+{
+  "variables":{
+    "region":"us-west-2",
+    "source_ami":"ami-80296ff8",
+    "source_image_name":"",
+    "image_name":"build-rhel6"
+  },
+  "builders":[
+    {
+      "type":"amazon-ebs",
+      "instance_type":"t2.micro",
+      "ami_name":"native-{{user `version`}}-{{user `image_name`}} {{timestamp}}",
+      "access_key":"{{user `aws_access_key`}}",
+      "secret_key":"{{user `aws_secret_key`}}",
+      "region":"{{user `region`}}",
+      "source_ami":"{{user `source_ami`}}",
+      "subnet_id":"{{user `subnet_id`}}",
+      "vpc_id":"{{user `vpc_id`}}",
+      "launch_block_device_mappings":[
+        {
+          "device_name":"/dev/sda1",
+          "delete_on_termination":true,
+          "volume_type": "gp2",
+          "volume_size":100
+        }
+      ],
+      "tags":{
+        "team":"native",
+        "version":"{{user `version`}}",
+        "source_ami":"{{user `source_ami`}}"
+      },
+      "ssh_username":"ec2-user",
+      "ssh_pty":true
+    }
+  ],
+  "provisioners":[
+    {
+      "type":"shell",
+      "script":"rhel/wait-for-cloud-init.sh"
+    },
+    {
+      "type":"shell",
+      "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
+      "scripts":[
+        "rhel/update.sh"
+      ]
+    },
+    {
+      "type":"file",
+      "source":"rhel/files",
+      "destination":"/tmp"
+    },
+    {
+      "type":"shell",
+      "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
+      "inline":[
+        "cp -rv /tmp/files/* /",
+        "rm -rf /tmp/files",
+        "chmod +x /etc/init-user.sh"
+      ]
+    },
+    {
+      "type":"shell",
+      "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
+      "scripts":[
+        "rhel/disable-selinux.sh",
+        "rhel/add-user-build.sh",
+        "rhel/install-scl-devtoolset.sh",
+        "rhel/install-build-rpms.sh",
+        "rhel/install-cmake.sh",
+        "rhel/install-jdk-1.8.sh"
+      ]
+    },
+    {
+      "type":"file",
+      "source":"{{user `gemfire_archive`}}",
+      "destination":"gemfire.tar.gz"
+    },
+    {
+      "type":"shell",
+      "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
+      "scripts":[
+        "rhel/install-gemfire.sh"
+      ]
+    },
+    {
+      "type":"shell",
+      "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
+      "scripts":[
+        "rhel/cleanup.sh"
+      ]
+    }
+  ]
+}
diff --git a/packer/build-ubuntu.json b/packer/build-ubuntu.json
index 8bfbeac..bf86055 100644
--- a/packer/build-ubuntu.json
+++ b/packer/build-ubuntu.json
@@ -63,7 +63,8 @@
         "ubuntu/add-user-build.sh",
         "ubuntu/install-packages.sh",
         "ubuntu/install-coverage-tools.sh",
-        "ubuntu/install-cmake.sh"
+        "ubuntu/install-cmake.sh",
+        "ubuntu/install-clang-format.sh"
       ]
     },
     {
diff --git a/packer/rhel-7-base.json b/packer/rhel-7-base.json
index cd03619..84d43f8 100644
--- a/packer/rhel-7-base.json
+++ b/packer/rhel-7-base.json
@@ -41,8 +41,7 @@
       "type":"shell",
       "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
       "scripts":[
-        "rhel/cleanup.sh",
-        "rhel/zerodisk.sh"
+        "rhel/cleanup.sh"
       ]
     }
   ]
diff --git a/packer/rhel/disable-selinux.sh b/packer/rhel/disable-selinux.sh
index 777b82d..9a8af60 100644
--- a/packer/rhel/disable-selinux.sh
+++ b/packer/rhel/disable-selinux.sh
@@ -17,11 +17,7 @@
 
 set -x -e -o pipefail
 
-bin=`dirname "$0"`
-bin=`cd "$bin">/dev/null; pwd`
-
-main() {
-  cat > /etc/sysconfig/selinux <<EOF
+cat > /etc/sysconfig/selinux <<EOF
 # This file controls the state of SELinux on the system.
 # SELINUX= can take one of these three values:
 #     enforcing - SELinux security policy is enforced.
@@ -34,7 +30,3 @@
 #     mls - Multi Level Security protection.
 SELINUXTYPE=targeted
 EOF
-
-}
-
-main "$@"
diff --git a/packer/rhel/zerodisk.sh b/packer/rhel/files/etc/cloud/cloud.cfg.d/10_hosts.cfg
similarity index 85%
copy from packer/rhel/zerodisk.sh
copy to packer/rhel/files/etc/cloud/cloud.cfg.d/10_hosts.cfg
index 809eb14..bb02494 100644
--- a/packer/rhel/zerodisk.sh
+++ b/packer/rhel/files/etc/cloud/cloud.cfg.d/10_hosts.cfg
@@ -1,24 +1,16 @@
-#!/usr/bin/env bash
-
 # 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.
 
-
-# TODO does this really help image launch times?
-
-exit 0
-
-dd if=/dev/zero of=/EMPTY bs=1M
-rm -f /
+manage_etc_hosts: true
diff --git a/packer/rhel/install-build-rpms.sh b/packer/rhel/install-build-rpms.sh
index 08cb45d..2809a1f 100644
--- a/packer/rhel/install-build-rpms.sh
+++ b/packer/rhel/install-build-rpms.sh
@@ -17,4 +17,7 @@
 
 set -x -e -o pipefail
 
-yum install -y git2u make doxygen zlib-devel patch openssl-devel
\ No newline at end of file
+yum install -y make doxygen zlib-devel patch openssl-devel
+
+yum install -y rh-git29
+echo "source scl_source enable rh-git29" >> ~build/.bashrc
diff --git a/packer/test-rhel-7.json b/packer/test-rhel-7.json
index 7ca6705..2b16e5d 100644
--- a/packer/test-rhel-7.json
+++ b/packer/test-rhel-7.json
@@ -90,9 +90,8 @@
       "type":"shell",
       "execute_command":"{{.Vars}} sudo -E -S bash '{{.Path}}'",
       "scripts":[
-        "rhel/cleanup.sh",
-        "rhel/zerodisk.sh"
+        "rhel/cleanup.sh"
       ]
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/packer/rhel/zerodisk.sh b/packer/ubuntu/install-clang-format.sh
similarity index 86%
rename from packer/rhel/zerodisk.sh
rename to packer/ubuntu/install-clang-format.sh
index 809eb14..03a1ce1 100644
--- a/packer/rhel/zerodisk.sh
+++ b/packer/ubuntu/install-clang-format.sh
@@ -6,19 +6,17 @@
 # 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.
 
+set -x -e -o pipefail
 
-# TODO does this really help image launch times?
+apt-get -y install clang-format-6.0
 
-exit 0
-
-dd if=/dev/zero of=/EMPTY bs=1M
-rm -f /
+ln -s /usr/bin/clang-format-6.0 /usr/bin/clang-format
\ No newline at end of file
diff --git a/packer/windows/install-openssl.ps1 b/packer/windows/install-openssl.ps1
index ef69b6f..9fcabf7 100644
--- a/packer/windows/install-openssl.ps1
+++ b/packer/windows/install-openssl.ps1
@@ -16,4 +16,4 @@
 $ErrorActionPreference = "Stop"
 Import-Module Packer -Force
 
-Install-Package https://slproweb.com/download/Win64OpenSSL-1_1_1b.exe -ArgumentList /silent
+Install-Package https://slproweb.com/download/Win64OpenSSL-1_1_1c.exe -ArgumentList /silent
diff --git a/tests/cpp/fwklib/FwkStrCvt.hpp b/tests/cpp/fwklib/FwkStrCvt.hpp
index c7914ce..bfbe1c8 100644
--- a/tests/cpp/fwklib/FwkStrCvt.hpp
+++ b/tests/cpp/fwklib/FwkStrCvt.hpp
@@ -23,7 +23,7 @@
 #include "config.h"
 
 #if defined(_MACOSX)
-#include <inttypes.h>
+#include <cinttypes>
 #endif
 
 #include <string>
diff --git a/tests/cpp/testobject/BatchObject.hpp b/tests/cpp/testobject/BatchObject.hpp
index 310eab5..8a8d29e 100644
--- a/tests/cpp/testobject/BatchObject.hpp
+++ b/tests/cpp/testobject/BatchObject.hpp
@@ -20,8 +20,7 @@
 #ifndef GEODE_TESTOBJECT_BATCHOBJECT_H_
 #define GEODE_TESTOBJECT_BATCHOBJECT_H_
 
-#include <inttypes.h>
-
+#include <cinttypes>
 #include <string>
 
 #include <ace/ACE.h>
diff --git a/tests/cpp/testobject/CMakeLists.txt b/tests/cpp/testobject/CMakeLists.txt
index 253b9ce..c5cfeb5 100644
--- a/tests/cpp/testobject/CMakeLists.txt
+++ b/tests/cpp/testobject/CMakeLists.txt
@@ -79,7 +79,6 @@
 target_compile_definitions(testobject
   PRIVATE
     BUILD_TESTOBJECT
-    __STDC_FORMAT_MACROS
 )
 
 target_include_directories(testobject
diff --git a/tests/cpp/testobject/DeltaFastAssetAccount.hpp b/tests/cpp/testobject/DeltaFastAssetAccount.hpp
index 30b1600..ad96bdc 100644
--- a/tests/cpp/testobject/DeltaFastAssetAccount.hpp
+++ b/tests/cpp/testobject/DeltaFastAssetAccount.hpp
@@ -20,8 +20,7 @@
 #ifndef GEODE_TESTOBJECT_DELTAFASTASSETACCOUNT_H_
 #define GEODE_TESTOBJECT_DELTAFASTASSETACCOUNT_H_
 
-#include <inttypes.h>
-
+#include <cinttypes>
 #include <string>
 
 #include <ace/ACE.h>
diff --git a/tests/cpp/testobject/DeltaPSTObject.hpp b/tests/cpp/testobject/DeltaPSTObject.hpp
index db548a7..ddab236 100644
--- a/tests/cpp/testobject/DeltaPSTObject.hpp
+++ b/tests/cpp/testobject/DeltaPSTObject.hpp
@@ -20,8 +20,7 @@
 #ifndef GEODE_TESTOBJECT_DELTAPSTOBJECT_H_
 #define GEODE_TESTOBJECT_DELTAPSTOBJECT_H_
 
-#include <inttypes.h>
-
+#include <cinttypes>
 #include <string>
 
 #include <ace/ACE.h>
diff --git a/tests/cpp/testobject/EqStruct.hpp b/tests/cpp/testobject/EqStruct.hpp
index 7b0333b..538063d 100644
--- a/tests/cpp/testobject/EqStruct.hpp
+++ b/tests/cpp/testobject/EqStruct.hpp
@@ -20,8 +20,7 @@
 #ifndef GEODE_TESTOBJECT_EQSTRUCT_H_
 #define GEODE_TESTOBJECT_EQSTRUCT_H_
 
-#include <inttypes.h>
-
+#include <cinttypes>
 #include <fwklib/FwkException.hpp>
 #include <string>
 
diff --git a/tests/cpp/testobject/FastAssetAccount.cpp b/tests/cpp/testobject/FastAssetAccount.cpp
index 1b907ac..9f154d5 100644
--- a/tests/cpp/testobject/FastAssetAccount.cpp
+++ b/tests/cpp/testobject/FastAssetAccount.cpp
@@ -17,7 +17,7 @@
 
 #include "FastAssetAccount.hpp"
 
-#include <inttypes.h>
+#include <cinttypes>
 
 #include "FastAsset.hpp"
 
diff --git a/tests/cpp/testobject/PSTObject.hpp b/tests/cpp/testobject/PSTObject.hpp
index c6f4a7f..fddb1c4 100644
--- a/tests/cpp/testobject/PSTObject.hpp
+++ b/tests/cpp/testobject/PSTObject.hpp
@@ -20,8 +20,7 @@
 #ifndef GEODE_TESTOBJECT_PSTOBJECT_H_
 #define GEODE_TESTOBJECT_PSTOBJECT_H_
 
-#include <inttypes.h>
-
+#include <cinttypes>
 #include <string>
 
 #include <ace/ACE.h>
diff --git a/tests/javaobject/NonDeserializableObject.java b/tests/javaobject/NonDeserializableObject.java
new file mode 100644
index 0000000..786c71a
--- /dev/null
+++ b/tests/javaobject/NonDeserializableObject.java
@@ -0,0 +1,67 @@
+/*
+ * 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.
+ */
+package javaobject;
+
+import org.apache.geode.DataSerializable;
+import org.apache.geode.Instantiator;
+import org.apache.geode.cache.Declarable;
+import java.io.*;
+
+//
+// NonDeserializableObject is, in general, deserializable, but on a Geode server
+// it can't be deserialized because it has no default ctor, and thus can't be
+// instantiated via reflection.  This is interesting because it's possible to,
+// for instance, execute a function server-side which returns an instance of
+// this class, which causes Geode to return a payload of type 'DataSerializable'
+// with subtype 'Class', and the class name and data necessary to recreate the
+// object in a client whieh supports reflection.  Since C++ doesn't have this,
+// the Geode Native Client should throw an exception, and that's what we use
+// this class to test.
+//
+public class NonDeserializableObject implements DataSerializable  {
+    static {
+        Instantiator.register(new NonDeserializableObjectInstantiator());
+    }
+
+   String m_str;
+
+   public NonDeserializableObject(String str){m_str = str;}
+
+   @Override
+   public void toData(DataOutput dataOutput) throws IOException {
+   }
+
+   @Override
+   public void fromData(DataInput dataInput) throws IOException, ClassNotFoundException {
+   }
+
+   public static class NonDeserializableObjectInstantiator extends Instantiator {
+        public NonDeserializableObjectInstantiator() {
+            super(NonDeserializableObject.class, 500);
+        }
+
+        public NonDeserializableObjectInstantiator(Class<? extends DataSerializable> c, int classId) {
+            super(c, classId);
+        }
+
+        @Override
+        public DataSerializable newInstance() {
+            return new NonDeserializableObject("foo");
+        }
+    }
+}
+
diff --git a/tests/javaobject/executeFunction_SendObjectWhichCantBeDeserialized.java b/tests/javaobject/executeFunction_SendObjectWhichCantBeDeserialized.java
new file mode 100644
index 0000000..69aa716
--- /dev/null
+++ b/tests/javaobject/executeFunction_SendObjectWhichCantBeDeserialized.java
@@ -0,0 +1,66 @@
+/*
+ * 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.
+ */
+package javaobject;
+
+import org.apache.geode.DataSerializable;
+import org.apache.geode.Instantiator;
+import org.apache.geode.cache.Declarable;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.RegionFunctionContext;
+
+import java.util.Properties;
+import java.io.*;
+
+import javaobject.NonDeserializableObject;
+
+public class executeFunction_SendObjectWhichCantBeDeserialized implements Function, Declarable {
+
+    public static final String NAME = "executeFunction_SendObjectWhichCantBeDeserialized";
+
+    @Override
+    public void execute(FunctionContext context) {
+        NonDeserializableObject myNonDeserializableObject = new NonDeserializableObject("123");
+        context.getResultSender().lastResult(myNonDeserializableObject);
+    }
+
+    @Override
+    public boolean hasResult() {
+        return true;
+    }
+
+    @Override
+    public boolean optimizeForWrite() {
+        return true;
+    }
+
+    @Override
+    public String getId() {
+        return NAME;
+    }
+
+   @Override
+    public boolean isHA() {
+        return true;
+    }
+
+    @Override
+    public void init(Properties props) {
+    }
+}
+
diff --git a/xsds/cpp-cache-1.10-DRAFT.xsd b/xsds/cpp-cache-1.10-DRAFT.xsd
new file mode 100644
index 0000000..38b57d9
--- /dev/null
+++ b/xsds/cpp-cache-1.10-DRAFT.xsd
@@ -0,0 +1,235 @@
+<?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.
+-->
+
+<xsd:schema 
+    targetNamespace="http://geode.apache.org/schema/cpp-cache"
+    xmlns:nc="http://geode.apache.org/schema/cpp-cache"
+    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+    elementFormDefault="qualified"
+    version="1.0">
+  <xsd:annotation>
+    <xsd:documentation><![CDATA[
+      This is the XML Schema for the Geode distributed cache declarative
+      caching XML file.  All declarative cache files must include a schema
+      of the following form:
+
+  <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/cpp-cache-1.10.xsd"
+      version="1.10">
+
+The contents of a declarative XML file correspond to APIs found in the
+org.apache.geode.cache and org.apache.geode.cache.client
+packages.  A declarative caching XML file is used to populate a Cache
+or a ClientCache when it is created.
+
+The top-level element in this syntax is "client-cache". All elements are
+listed here in alphabetical order.
+
+The following conventions apply to all Geode distributed cache
+declarative caching XML file elements unless indicated otherwise.
+
+- In elements that contain PCDATA, leading and trailing whitespace in
+  the data may be ignored.
+
+- In elements whose value is an "enumerated type", the value is case
+  sensitive.
+    
+  ]]></xsd:documentation>
+  </xsd:annotation>
+  <xsd:element name="client-cache">
+    <xsd:complexType>
+      <xsd:choice minOccurs="0" maxOccurs="unbounded">
+        <xsd:element minOccurs="0" maxOccurs="unbounded" name="pool">
+          <xsd:complexType>
+            <xsd:choice>
+              <xsd:element maxOccurs="unbounded" name="locator" type="nc:host-port-type" />
+              <xsd:element maxOccurs="unbounded" name="server" type="nc:host-port-type" />
+            </xsd:choice>
+            <xsd:attribute name="name" type="xsd:string" use="required" />
+            <xsd:attribute name="free-connection-timeout" type="nc:duration-type" />
+            <xsd:attribute name="load-conditioning-interval" type="nc:duration-type" />
+            <xsd:attribute name="min-connections" type="xsd:string" />
+            <xsd:attribute name="max-connections" type="xsd:string" />
+            <xsd:attribute name="retry-attempts" type="xsd:string" />
+            <xsd:attribute name="idle-timeout" type="nc:duration-type" />
+            <xsd:attribute name="ping-interval" type="nc:duration-type" />
+            <xsd:attribute name="read-timeout" type="nc:duration-type" />
+            <xsd:attribute name="server-group" type="xsd:string" />
+            <xsd:attribute name="socket-buffer-size" type="xsd:string" />
+            <xsd:attribute name="subscription-enabled" type="xsd:boolean" />
+            <xsd:attribute name="subscription-message-tracking-timeout" type="nc:duration-type" />
+            <xsd:attribute name="subscription-ack-interval" type="nc:duration-type" />
+            <xsd:attribute name="subscription-redundancy" type="xsd:string" />
+            <xsd:attribute name="statistic-interval" type="nc:duration-type" />
+            <xsd:attribute name="pr-single-hop-enabled" type="xsd:boolean" />
+            <xsd:attribute name="thread-local-connections" type="xsd:boolean" />
+            <xsd:attribute name="multiuser-authentication" type="xsd:boolean" />
+            <xsd:attribute name="update-locator-list-interval" type="nc:duration-type" />
+          </xsd:complexType>
+        </xsd:element>
+        <xsd:element minOccurs="0" maxOccurs="unbounded" name="region" type="nc:region-type" />
+        <xsd:element minOccurs="0" name="pdx">
+          <xsd:complexType>
+            <xsd:attribute name="ignore-unread-fields" type="xsd:boolean" />
+            <xsd:attribute name="read-serialized" type="xsd:boolean" />
+          </xsd:complexType>
+        </xsd:element>
+      </xsd:choice>
+      <xsd:attribute name="version" type="nc:version-type" use="required" fixed="1.10" />
+    </xsd:complexType>
+  </xsd:element>
+
+  <xsd:complexType name="region-type">
+    <xsd:sequence>
+      <xsd:element minOccurs="0" name="region-attributes" type="nc:region-attributes-type" />
+      <xsd:element minOccurs="0" maxOccurs="unbounded" name="region" type="nc:region-type" />
+    </xsd:sequence>
+    <xsd:attribute name="name" type="xsd:string" use="required" />
+    <xsd:attribute name="refid" type="xsd:string" />
+  </xsd:complexType>
+
+  <xsd:complexType name="region-attributes-type">
+    <xsd:sequence>
+      <xsd:choice minOccurs="0" maxOccurs="unbounded">
+        <xsd:element name="region-time-to-live" type="nc:expiration-type" />
+        <xsd:element name="region-idle-time" type="nc:expiration-type" />
+        <xsd:element name="entry-time-to-live" type="nc:expiration-type" />
+        <xsd:element name="entry-idle-time" type="nc:expiration-type" />
+        <xsd:element name="partition-resolver" type="nc:library-type" />
+        <xsd:element name="cache-loader" type="nc:library-type" />
+        <xsd:element name="cache-listener" type="nc:library-type" />
+        <xsd:element name="cache-writer" type="nc:library-type" />
+        <xsd:element name="persistence-manager">
+          <xsd:complexType>
+            <xsd:complexContent>
+              <xsd:extension base="nc:library-type">
+                <xsd:sequence>
+                  <xsd:element name="properties">
+                    <xsd:complexType>
+                      <xsd:sequence>
+                        <xsd:element minOccurs="0" maxOccurs="unbounded" name="property">
+                          <xsd:complexType>
+                            <xsd:attribute name="name" type="xsd:string" use="required" />
+                            <xsd:attribute name="value" type="xsd:string" use="required" />
+                          </xsd:complexType>
+                        </xsd:element>
+                      </xsd:sequence>
+                    </xsd:complexType>
+                  </xsd:element>
+                </xsd:sequence>
+              </xsd:extension>
+            </xsd:complexContent>
+          </xsd:complexType>
+        </xsd:element>
+      </xsd:choice>
+    </xsd:sequence>
+    <xsd:attribute name="caching-enabled" type="xsd:boolean" />
+    <xsd:attribute name="cloning-enabled" type="xsd:boolean" />
+    <xsd:attribute name="scope">
+      <xsd:simpleType>
+        <xsd:restriction base="xsd:NMTOKEN">
+          <xsd:enumeration value="local" />
+          <xsd:enumeration value="distributed-no-ack" />
+          <xsd:enumeration value="distributed-ack" />
+        </xsd:restriction>
+      </xsd:simpleType>
+    </xsd:attribute>
+    <xsd:attribute name="initial-capacity" type="xsd:string" />
+    <xsd:attribute name="load-factor" type="xsd:string" />
+    <xsd:attribute name="concurrency-level" type="xsd:string" />
+    <xsd:attribute name="lru-entries-limit" type="xsd:string" />
+    <xsd:attribute name="disk-policy">
+      <xsd:simpleType>
+        <xsd:restriction base="xsd:NMTOKEN">
+          <xsd:enumeration value="none" />
+          <xsd:enumeration value="overflows" />
+          <xsd:enumeration value="persist" />
+        </xsd:restriction>
+      </xsd:simpleType>
+    </xsd:attribute>
+    <xsd:attribute name="endpoints" type="xsd:string" />
+    <xsd:attribute name="client-notification" type="xsd:boolean" />
+    <xsd:attribute name="pool-name" type="xsd:string" />
+    <xsd:attribute name="concurrency-checks-enabled" type="xsd:boolean" />
+    <xsd:attribute name="id" type="xsd:string" />
+    <xsd:attribute name="refid" type="xsd:string" />
+  </xsd:complexType>
+
+  <xsd:complexType name="expiration-type">
+    <xsd:sequence>
+      <xsd:element name="expiration-attributes">
+        <xsd:complexType>
+          <xsd:attribute name="timeout" type="nc:duration-type" use="required" />
+          <xsd:attribute name="action">
+            <xsd:simpleType>
+              <xsd:restriction base="xsd:NMTOKEN">
+                <xsd:enumeration value="invalidate" />
+                <xsd:enumeration value="destroy" />
+                <xsd:enumeration value="local-invalidate" />
+                <xsd:enumeration value="local-destroy" />
+              </xsd:restriction>
+            </xsd:simpleType>
+          </xsd:attribute>
+        </xsd:complexType>
+      </xsd:element>
+    </xsd:sequence>
+  </xsd:complexType>
+
+  <xsd:complexType name="host-port-type">
+    <xsd:attribute name="host" type="xsd:string" use="required" />
+    <xsd:attribute name="port" type="nc:port-type" use="required" />
+  </xsd:complexType>
+
+  <xsd:simpleType name="port-type">
+    <xsd:restriction base="xsd:int">
+      <xsd:minInclusive value="0" />
+      <xsd:maxInclusive value="65535" />
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:simpleType name="version-type">
+    <xsd:annotation>
+      <xsd:documentation>
+        Decimal version type.
+      </xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:token">
+      <xsd:pattern value="\.?[0-9]+(\.[0-9]+)*" />
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:simpleType name="duration-type">
+    <xsd:annotation>
+      <xsd:documentation>
+        Time duration in positive integer and unit.
+      </xsd:documentation>
+    </xsd:annotation>
+    <xsd:restriction base="xsd:token">
+      <xsd:pattern value="\d+(h|min|s|ms|us|ns)" />
+    </xsd:restriction>
+  </xsd:simpleType>
+
+  <xsd:complexType name="library-type">
+    <xsd:attribute name="library-name" type="xsd:string" />
+    <xsd:attribute name="library-function-name" type="xsd:string" use="required" />
+  </xsd:complexType>
+
+</xsd:schema>