diff --git a/.ratignore b/.ratignore
index c40208a..7f4a17a 100644
--- a/.ratignore
+++ b/.ratignore
@@ -26,17 +26,6 @@
 # docker/
 bellsoft.repo
 
-# contrib/pdxautoserializer
-# public domain sources
-CPPDictionary.hpp
-CPPSymbol.hpp
-CPP_parser.g
-DictEntry.hpp
-Dictionary.cpp
-Dictionary.hpp
-STDCTokenTypes.txt
-Support.cpp
-
 # well known build directories
 build
 cmake-build-.*
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ab41223..fc8350a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -48,8 +48,6 @@
   set(CMAKE_BUILD_TYPE Debug CACHE STRING "Specifies the build type on single-configuration generators." FORCE)
 endif()
 
-set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "4.5.2")
-set(DOTNET_TARGET_FRAMEWORK_VERSION "4.5.2")
 set(BUILD_BITS 64 CACHE STRING "Build for 64 (Geode default) or 32 bit.")
 option(BUILD_BENCHMARKS "Build benchmarks" ON)
 
@@ -139,13 +137,8 @@
 
 list(APPEND CPACK_SOURCE_IGNORE_FILES ${IGNORED_FULL})
 
-if(CMAKE_GENERATOR MATCHES Win64*)
-  set(CMAKE_GENERATOR_TOOLSET "host=x64")
-else()
-  set(CMAKE_GENERATOR_TOOLSET )
-endif()
-
 include(CPack)
+
 include(CheckCXXCompilerFlag)
 include(CheckCCompilerFlag)
 
@@ -274,6 +267,8 @@
   endif()
 
 elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
+  set(CMAKE_DOTNET_TARGET_FRAMEWORK_VERSION "v4.5.2")
+
   set(BUILD_CLI 1)
 
   # Interface for C++/CLI language.
@@ -302,6 +297,12 @@
     string(REPLACE "\n" "" STRONG_NAME_PUBLIC_KEY ${STRONG_NAME_PUBLIC_KEY})
     string(REGEX REPLACE ".*sha1\\):([a-f0-9]+).*" "\\1" STRONG_NAME_PUBLIC_KEY ${STRONG_NAME_PUBLIC_KEY})
   endif()
+
+  find_program(NUGET nuget)
+  add_custom_target(nuget-restore 
+    COMMAND ${NUGET} restore ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.sln
+  )
+
 endif()
 
 find_package(Java 1.8.0.60 REQUIRED COMPONENTS Development)
@@ -376,6 +377,7 @@
 add_subdirectory(examples)
 if (${BUILD_CLI})
   add_subdirectory(clicache)
+  add_subdirectory(templates/security/csharp)
 endif()
 add_subdirectory(tests)
 
diff --git a/ci/lib/templates.lib.txt b/ci/lib/templates.lib.txt
index 5e7a5d9..0b3e5b4 100644
--- a/ci/lib/templates.lib.txt
+++ b/ci/lib/templates.lib.txt
@@ -72,43 +72,12 @@
 
 (@- end @)
 
-(@ def run_cpp_unit_tests(): -@)
+(@ def ctest_bash_task(path, timeout=300, parallel=6): -@)
 set -ueo pipefail
 (@= remote_functions() @)
-remote_shell cmake -E chdir build/cppcache/test ctest -C ${CMAKE_CONFIG} -j8 --timeout=500 --output-on-failure --schedule-random
+remote_shell cmake -E chdir (@= path @) ctest -C ${CMAKE_CONFIG} -j(@= str(parallel) @) --timeout=(@= str(timeout) @) --output-on-failure --repeat until-pass:4 --schedule-random
 (@- end @)
 
-(@ def run_cpp_integration_tests(): -@)
-set -ueo pipefail
-(@= remote_functions() @)
-remote_shell cmake -E chdir build/cppcache/integration/test ctest -C ${CMAKE_CONFIG} -j6 --timeout=500 --output-on-failure --repeat until-pass:4  --schedule-random
-(@- end @)
-
-(@ def run_cpp_legacy_integration_tests(): -@)
-set -ueo pipefail
-(@= remote_functions() @)
-remote_shell cmake -E chdir build/cppcache/integration-test ctest -C ${CMAKE_CONFIG} -j4 --timeout=500 --output-on-failure --repeat until-pass:4  --schedule-random
-(@- end @)
-
-(@ def run_net_unit_tests(): -@)
-set -ueo pipefail
-(@= remote_functions() @)
-remote_shell cmake -E chdir build/clicache/test2 ../packages/xunit.runner.console.2.4.0/tools/net452/xunit.console.exe ${CMAKE_CONFIG}/Apache.Geode.Tests2.dll -parallel all
-(@- end @)
-
-(@ def run_net_integration_tests(): -@)
-set -ueo pipefail
-(@= remote_functions() @)
-remote_shell cmake -E chdir build/clicache/integration-test2 ../packages/xunit.runner.console.2.4.0/tools/net452/xunit.console.exe ${CMAKE_CONFIG}/Apache.Geode.IntegrationTests2.dll -verbose -maxthreads 6
-(@- end @)
-
-(@ def run_net_legacy_integration_tests(): -@)
-set -ueo pipefail
-(@= remote_functions() @)
-remote_shell cmake -E chdir build/clicache/integration-test ctest -C ${CMAKE_CONFIG} -j6 --timeout=1000 --output-on-failure --repeat until-pass:4
-(@- end @)
-
-
 (@ def clang_tidy_bash_task(): -@)
 set -ueo pipefail
 export GEODE_HOME=$(pwd)/geode/expanded/apache-geode-$(cat geode/version)
diff --git a/ci/lib/templates.lib.yml b/ci/lib/templates.lib.yml
index 7551589..9446506 100644
--- a/ci/lib/templates.lib.yml
+++ b/ci/lib/templates.lib.yml
@@ -24,12 +24,7 @@
 #@      "remote_functions",
 #@      "instance_variables",
 #@      "google_variables",
-#@      "run_cpp_unit_tests",
-#@      "run_cpp_integration_tests",
-#@      "run_cpp_legacy_integration_tests",
-#@      "run_net_unit_tests",
-#@      "run_net_integration_tests",
-#@      "run_net_legacy_integration_tests",
+#@      "ctest_bash_task",
 #@      "clang_tidy_bash_task",
 #@      "clang_format_bash_task",
 #@      "rat_check_bash_task",
@@ -164,40 +159,6 @@
 #@ end
 
 ---
-#@ def packer_build_task(build):
-#@ end
-
----
-#@ def cpp_unit_test_task(build, config):
-#@ return remote_task("cpp-unit-tests", config.config, run_cpp_unit_tests(), "30m", build.params)
-#@ end
-
----
-#@ def cpp_integration_test_task(build, config):
-#@ return remote_task("cpp-integration-tests", config.config, run_cpp_integration_tests(), "1h", build.params)
-#@ end
-
----
-#@ def cpp_legacy_integration_test_task(build, config):
-#@ return remote_task("cpp-legacy-integration-tests", config.config, run_cpp_legacy_integration_tests(), "2h", build.params)
-#@ end
-
----
-#@ def net_unit_test_task(build, config):
-#@ return remote_task("net-unit-tests", config.config, run_net_unit_tests(), "30m", build.params)
-#@ end
-
----
-#@ def net_integration_test_task(build, config):
-#@ return remote_task("net-integration-tests", config.config, run_net_integration_tests(), "1h", build.params)
-#@ end
-
----
-#@ def net_legacy_integration_test_task(build, config):
-#@ return remote_task("net-legacy-integration-tests", config.config, run_net_legacy_integration_tests(), "2h", build.params)
-#@ end
-
----
 #@ def download_build_task():
 #@ return bash_task("download-build", [{"name":"instance"}], [{"name":"build"}], download_build_bash_task())
 #@ end
@@ -227,13 +188,14 @@
                   - get: #@ gci_resource_name(image_family_name(build.image_family))
             - #@ create_instance_task(build, config)
   - #@ build_task(config.config, build.params)
-  - #@ cpp_unit_test_task(build, config)
-  - #@ cpp_integration_test_task(build, config)
-  - #@ cpp_legacy_integration_test_task(build, config)
+  - #@ remote_task("cpp-unit-tests", config.config, ctest_bash_task("build/cppcache/test", parallel=8), "30m", build.params)
+  - #@ remote_task("cpp-integration-tests", config.config, ctest_bash_task("build/cppcache/integration/test", timeout=500), "1h", build.params)
+  - #@ remote_task("cpp-legacy-integration-tests", config.config, ctest_bash_task("build/cppcache/integration-test", 500), "2h", build.params)
   #@ if build.with_dot_net:
-  - #@ net_unit_test_task(build, config)
-  - #@ net_integration_test_task(build, config)
-  - #@ net_legacy_integration_test_task(build, config)
+  - #@ remote_task("net-unmanaged-unit-tests", config.config, ctest_bash_task("build/clicache/test", parallel=8), "10m", build.params)
+  - #@ remote_task("net-unit-tests", config.config, ctest_bash_task("build/clicache/test2", parallel=8), "30m", build.params)
+  - #@ remote_task("net-integration-tests", config.config, ctest_bash_task("build/clicache/integration-test2"), "1h", build.params)
+  - #@ remote_task("net-legacy-integration-tests", config.config, ctest_bash_task("build/clicache/integration-test"), "2h", build.params)
   #@ end
 on_failure:
   in_parallel:
diff --git a/clicache/CMakeLists.txt b/clicache/CMakeLists.txt
index 9df76a7..d2217a4 100644
--- a/clicache/CMakeLists.txt
+++ b/clicache/CMakeLists.txt
@@ -13,15 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cmake_minimum_required(VERSION 3.10)
-
-project(clicache_src)
-
-find_program(NUGET nuget)
-add_custom_target(nuget-restore 
-  COMMAND ${NUGET} restore ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}.sln
-)
-
 add_subdirectory(src)
 add_subdirectory(test)
 add_subdirectory(test2)
diff --git a/clicache/acceptance-test/CMakeLists.txt b/clicache/acceptance-test/CMakeLists.txt
index b73bcb2..79e2b13 100644
--- a/clicache/acceptance-test/CMakeLists.txt
+++ b/clicache/acceptance-test/CMakeLists.txt
@@ -49,19 +49,16 @@
 )
 
 set_target_properties( ${PROJECT_NAME} PROPERTIES
-  COMMON_LANGUAGE_RUNTIME ""
   VS_GLOBAL_ROOTNAMESPACE ${PROJECT_NAME}
   VS_GLOBAL_TreatWarningsAsErrors True
   VS_GLOBAL_TestProjectType UnitTest
   VS_GLOBAL_PROJECT_TYPES "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
   VS_DOTNET_REFERENCES "System;System.Xml;System.Web;System.Configuration"
-  VS_DOTNET_REFERENCE_Microsoft.VisualStudio.TestPlatform.TestFramework "${CMAKE_BINARY_DIR}/clicache/packages/Microsoft.VisualStudio.TestPlatform.14.0.0.1/lib/net20/Microsoft.VisualStudio.TestPlatform.TestFramework.dll"
-  VS_DOTNET_REFERENCE_Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions "${CMAKE_BINARY_DIR}/clicache/packages/Microsoft.VisualStudio.TestPlatform.14.0.0.1/lib/net20/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll"
-  VS_DOTNET_REFERENCE_xunit.core "${CMAKE_BINARY_DIR}/clicache/packages/xunit.extensibility.core.2.4.0/lib/netstandard1.1/xunit.core.dll"
-  VS_DOTNET_REFERENCE_xunit.assert "${CMAKE_BINARY_DIR}/clicache/packages/xunit.assert.2.4.0/lib/netstandard1.1/xunit.assert.dll"
-  VS_DOTNET_REFERENCE_xunit.abstractions "${CMAKE_BINARY_DIR}/clicache/packages/xunit.abstractions.2.0.2/lib/net35/xunit.abstractions.dll"
-  VS_DOTNET_REFERENCE_xunit.execution.desktop "${CMAKE_BINARY_DIR}/clicache/packages/xunit.extensibility.execution.2.4.0/lib/net452/xunit.execution.desktop.dll"
-  VS_DOTNET_REFERENCE_xunit.runner.visualstudio.testadapter "${CMAKE_BINARY_DIR}/clicache/packages/xunit.runner.visualstudio.2.4.0/build/_common/xunit.runner.visualstudio.testadapter.dll"
+  VS_DOTNET_REFERENCE_xunit.core "${CMAKE_BINARY_DIR}/packages/xunit.extensibility.core.2.4.0/lib/netstandard1.1/xunit.core.dll"
+  VS_DOTNET_REFERENCE_xunit.assert "${CMAKE_BINARY_DIR}/packages/xunit.assert.2.4.0/lib/netstandard1.1/xunit.assert.dll"
+  VS_DOTNET_REFERENCE_xunit.abstractions "${CMAKE_BINARY_DIR}/packages/xunit.abstractions.2.0.2/lib/net35/xunit.abstractions.dll"
+  VS_DOTNET_REFERENCE_xunit.execution.desktop "${CMAKE_BINARY_DIR}/packages/xunit.extensibility.execution.2.4.0/lib/net452/xunit.execution.desktop.dll"
+  VS_DOTNET_REFERENCE_xunit.runner.visualstudio.testadapter "${CMAKE_BINARY_DIR}/packages/xunit.runner.visualstudio.2.4.0/build/_common/xunit.runner.visualstudio.testadapter.dll"
   FOLDER cli/test/acceptance
 )
 
diff --git a/clicache/acceptance-test/packages.config b/clicache/acceptance-test/packages.config
index e7d725b..fb25d57 100644
--- a/clicache/acceptance-test/packages.config
+++ b/clicache/acceptance-test/packages.config
@@ -16,7 +16,6 @@
   limitations under the License.
 -->
 <packages>
-  <package id="Microsoft.VisualStudio.TestPlatform" version="14.0.0.1" targetFramework="net452" />
   <package id="xunit" version="2.4.0" targetFramework="net452" />
   <package id="xunit.abstractions" version="2.0.2" targetFramework="net35" />
   <package id="xunit.analyzers" version="0.10.0" targetFramework="net452" />
diff --git a/clicache/integration-test/AckMixTests.cs b/clicache/integration-test/AckMixTests.cs
deleted file mode 100644
index 8cf394d..0000000
--- a/clicache/integration-test/AckMixTests.cs
+++ /dev/null
@@ -1,264 +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.
- */
-
-using System;
-using System.Threading;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  [Category("unicast_only")]
-  public class AckMixTests : UnitTests
-  {
-    private TallyListener m_listener = new TallyListener();
-    private AckMixRegionWrapper m_regionw;
-    private const string RegionName = "ConfusedScope";
-
-    private UnitProcess m_client1, m_client2;
-
-    protected override ClientBase[] GetClients()
-    {
-      m_client1 = new UnitProcess();
-      m_client2 = new UnitProcess();
-      return new ClientBase[] { m_client1, m_client2 };
-    }
-
-    #region Private functions
-
-    private void Init()
-    {
-      Properties dsysConfig = new Properties();
-      dsysConfig.Insert("ack-wait-threshold", "5");
-      CacheHelper.InitConfig(dsysConfig);
-    }
-
-    #endregion
-
-    #region Functions called by the tests
-
-    public void CreateRegionNOIL(int clientNum, bool ack)
-    {
-      Init();
-      string ackStr;
-      if (ack)
-      {
-        ackStr = "with-ack";
-      }
-      else
-      {
-        ackStr = "no-ack";
-      }
-      Util.Log("Creating region in client {0}, " + ackStr +
-        ", no-mirror, cache, no-interestlist, with-listener", clientNum);
-      CacheHelper.CreateILRegion(RegionName, ack, true, m_listener);
-      m_regionw = new AckMixRegionWrapper(RegionName);
-    }
-
-    //Verify no events received by the process
-    public void VerifyNoEvents()
-    {
-      Util.Log("Verifying TallyListener has received nothing.");
-      Assert.AreEqual(0, m_listener.Creates, "Should be no creates");
-      Assert.AreEqual(0, m_listener.Updates, "Should be no updates");
-      Assert.IsNull(m_listener.LastKey, "Should be no key");
-      Assert.IsNull(m_listener.LastValue, "Should be no value");
-    }
-
-    public void SendCreate()
-    {
-      Util.Log("put(1,1) from Client 1 noack");
-      m_regionw.Put(1, 1);
-      m_listener.ShowTallies();
-    }
-
-    //Test cache didn't stored update
-    public void TestCreateFromAck()
-    {
-      Util.Log("test(1, -1) in Client 2 ack");
-      m_regionw.Test(1, -1);
-
-      // now define something of our own to test create going the other way.
-      Util.Log("put(2,2) from Client 2");
-      m_regionw.Put(2, 2);
-      Assert.AreEqual(1, m_listener.Creates, "Should be 1 create.");
-      // send update from ACK to NOACK
-      Util.Log("put(1,3) from Client 2");
-
-      Thread.Sleep(10000); // see if we can drop the incoming create before we define the key.
-      m_regionw.Test(1, -1);
-
-      m_regionw.Put(1, 3);
-      Assert.AreEqual(2, m_listener.Creates, "Should be 2 creates.");
-      m_listener.ShowTallies();
-    }
-
-    public void TestCreateFromNoAck()
-    {
-      Util.Log("test( 2, -1 ) in Client 1");
-      m_regionw.Test(2, -1);
-      Util.Log("test( 1, 3 ) in Client 1");
-      m_regionw.Test(1, 3);
-
-      // Now Updates from Client 1 to Client 2.
-      Util.Log("put( 1, 5) from Client 1");
-      m_regionw.Put(1, 5);
-      m_listener.ShowTallies();
-    }
-
-    public void TestUpdateFromAck()
-    {
-      Util.Log("test( 1, 5 ) in Client 2");
-      m_regionw.Test(1, 5, true);
-    }
-
-    public void TestEventCount(int clientNum)
-    {
-      Util.Log("check Client {0} event count.", clientNum);
-      m_listener.ShowTallies();
-      Assert.AreEqual(2, m_listener.ExpectCreates(2), "Should have been 2 creates.");
-      Assert.AreEqual(1, m_listener.ExpectUpdates(1), "Should have been 1 update.");
-    }
-
-    public void TestTimeoutSetup()
-    {
-      Util.Log("creating after timeout key to verify.");
-      m_regionw.Put(40000, 1);
-      m_regionw.SetupTimeout(m_listener);
-    }
-
-    public void TestPutTimeout(int newVal)
-    {
-      Util.Log("checking that timeout works.");
-      try
-      {
-        m_listener.IgnoreTimeout = true;
-        m_regionw.RequestTimeout();
-        Assert.Fail("Should have thrown TimeoutException.");
-      }
-      catch (TimeoutException)
-      {
-        // good.. expected this... now sleep a bit and move on.
-        Util.Log("Expected: Received TimeoutException ( good news. )");
-        m_listener.IgnoreTimeout = false;
-        Thread.Sleep(10000); // other process should be clear by now.
-        m_regionw.Put(40000, newVal); // Make sure we succeed with this next put.
-        Util.Log("Sent update to key 40000.");
-      }
-      catch (Exception ex)
-      {
-        Util.Log(ex.ToString());
-        Assert.Fail(ex.Message);
-      }
-    }
-
-    public void TestAfterPutTimeout(int newVal)
-    {
-      Util.Log("verifing values made it through from TestTimeout.");
-      m_regionw.CheckTimeout();
-      m_regionw.Test(40000, newVal);
-    }
-
-    #endregion
-
-    [Test]
-    public void AckMix()
-    {
-      m_client1.Call(CreateRegionNOIL, 1, false);
-      m_client2.Call(CreateRegionNOIL, 2, true);
-
-      m_client1.Call(VerifyNoEvents);
-      m_client2.Call(VerifyNoEvents);
-
-      m_client1.Call(SendCreate);
-      m_client2.Call(TestCreateFromAck);
-
-      m_client1.Call(TestCreateFromNoAck);
-      m_client2.Call(TestUpdateFromAck);
-
-      m_client1.Call(TestEventCount, 1);
-      m_client2.Call(TestEventCount, 2);
-
-      m_client1.Call(TestTimeoutSetup);
-      m_client2.Call(TestPutTimeout, 4000);
-
-      m_client1.Call(TestAfterPutTimeout, 4000);
-      m_client2.Call(TestPutTimeout, 5000);
-
-      m_client1.Call(TestAfterPutTimeout, 5000);
-    }
-  }
-
-  class AckMixRegionWrapper : RegionWrapper
-  {
-    private bool m_timeoutUpdate;
-
-    private static CacheableString timeoutKey =
-      new CacheableString("timeout");
-
-    public AckMixRegionWrapper(string name)
-      : base(name)
-    {
-      m_timeoutUpdate = false;
-    }
-
-    public void RequestTimeout()
-    {
-      string timeoutValue = "timeout";
-      if (m_timeoutUpdate)
-      {
-        timeoutValue = "timeoutUpdate";
-      }
-      DateTime start = DateTime.Now;
-      TimeSpan span;
-      try
-      {
-        m_region.Put(timeoutKey, timeoutValue);
-        span = DateTime.Now - start;
-        Util.Log("put took {0} millis value({1})", span.TotalMilliseconds, timeoutValue);
-      }
-      catch
-      {
-        span = DateTime.Now - start;
-        Util.Log("put took {0} millis value({1})", span.TotalMilliseconds, timeoutValue);
-        m_timeoutUpdate = true;
-        throw;
-      }
-    }
-
-    public void CheckTimeout()
-    {
-      string timeoutValue = "timeout";
-      if (m_timeoutUpdate)
-      {
-        timeoutValue = "timeoutUpdate";
-      }
-      CacheableString val = m_region.Get(timeoutKey) as CacheableString;
-      Assert.AreEqual(timeoutValue, val.ToString());
-      m_timeoutUpdate = true;
-    }
-
-    public void SetupTimeout(TallyListener listener)
-    {
-      listener.IgnoreTimeout = true;
-      m_region.Put(timeoutKey, timeoutKey);
-      listener.IgnoreTimeout = false;
-    }
-  }
-}
diff --git a/clicache/integration-test/BuiltinCacheableWrappersN.cs b/clicache/integration-test/BuiltinCacheableWrappersN.cs
index efc86b8..7f0ee18 100644
--- a/clicache/integration-test/BuiltinCacheableWrappersN.cs
+++ b/clicache/integration-test/BuiltinCacheableWrappersN.cs
@@ -112,6 +112,8 @@
       return ~crc32;
     }
 
+#pragma warning disable 618
+
     public static bool IsContainerTypeId(uint typeId)
     {
       return (typeId == GeodeClassIds.CacheableObjectArray) ||
diff --git a/clicache/integration-test/CMakeLists.txt b/clicache/integration-test/CMakeLists.txt
index d94d2e7..d879008 100644
--- a/clicache/integration-test/CMakeLists.txt
+++ b/clicache/integration-test/CMakeLists.txt
@@ -13,108 +13,110 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-project(nativeclient.tests.clicache)
+project(Apache.Geode.Client.UnitTests CSharp )
 
-set (NUNIT "C:\\Program Files (x86)\\NUnit 2.6.4")
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages.config ${CMAKE_CURRENT_BINARY_DIR}/packages.config COPYONLY)
 
-if (64 EQUAL ${BUILD_BITS})
-  set (NUNIT_CONSOLE "nunit-console")
-else()
-  set (NUNIT_CONSOLE "nunit-console-x86")
+file(GLOB_RECURSE SOURCE RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cs")
+file(GLOB_RECURSE XML_SOURCE RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.xml")
+set(RESOURCES
+  ${XML_SOURCE}
+  geode.properties.mixed
+  geode.properties.nativeclient
+  system.properties
+)
+
+add_library(Apache.Geode.Client.UnitTests SHARED
+  NUnitTestAddTests.ps1
+  packages.config
+  test.runsettings.in
+  ${SOURCE}
+  ${RESOURCES}
+)
+
+source_group("Source Files" FILES "${SOURCE}")
+source_group("Resource Files" FILES ${RESOURCES})
+
+set_source_files_properties(
+  ${RESOURCES}
+  PROPERTIES
+    VS_COPY_TO_OUT_DIR PreserveNewest
+    VS_TOOL_OVERRIDE None
+)
+
+target_link_libraries(Apache.Geode.Client.UnitTests
+  PUBLIC
+    Apache.Geode
+    DUnitFramework
+    NewTestObject
+    PdxClassLibrary
+    PdxVersion1Lib
+    PdxVersion2Lib
+    QueryWrapper
+    SecurityUtil
+)
+
+set_target_properties(Apache.Geode.Client.UnitTests PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE "Apache.Geode.Client.UnitTests"
+  VS_GLOBAL_TreatWarningsAsErrors False
+  VS_GLOBAL_IsTestProject True
+  VS_GLOBAL_TestProjectType UnitTest
+  VS_GLOBAL_RunSettingsFilePath "\$(MSBuildProjectDirectory)\\test.runsettings"
+  VS_GLOBAL_PROJECT_TYPES "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Web;System.Configuration;System.Management"
+  VS_DOTNET_REFERENCE_NUnit "${CMAKE_BINARY_DIR}/packages/NUnit.2.6.4/lib/nunit.framework.dll"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(Apache.Geode.Client.UnitTests PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
 endif()
 
+add_dependencies(Apache.Geode.Client.UnitTests FwkClient SqLiteImpl)
+add_dependencies(Apache.Geode.Client.UnitTests nuget-restore)
 
-foreach(var CMAKE_CURRENT_SOURCE_DIR CMAKE_SOURCE_DIR CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR)
-  file(TO_NATIVE_PATH ${${var}} ${var}_NATIVE)
-endforeach()
 
-file(GLOB_RECURSE CSPROJECTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.csproj.in")
-if(EXISTS "${STRONG_NAME_KEY}")
-  set(STRONG_NAME_KEY_ENABLED true)
-endif()
-
-foreach(FILE ${CSPROJECTS})
-  # TODO: make this a one line MATCH statement
-  string(REGEX REPLACE "\\.csproj.in" "" PROJDIR ${FILE})
-  string(REGEX REPLACE ".*/" "" PROJNAME ${PROJDIR})
-  configure_file(${FILE} ${CMAKE_CURRENT_BINARY_DIR}/${PROJNAME}.csproj)
-  include_external_msproject(
-      ${PROJNAME}  ${CMAKE_CURRENT_BINARY_DIR}/${PROJNAME}.csproj
-      TYPE FAE04EC0-301F-11D3-BF4B-00C04F79EFBC)
-  set_target_properties(${PROJNAME} PROPERTIES FOLDER cli/test/integration)
-
-endforeach()
+configure_file(test.runsettings.in test.runsettings.gen)
+file(GENERATE OUTPUT test.runsettings INPUT ${CMAKE_CURRENT_BINARY_DIR}/test.runsettings.gen)
 
 enable_testing()
 
-# Function to resolve both config and generate stage variables.
-macro(generate_config INPUT TEMP OUTPUT)
-    configure_file(${INPUT} ${TEMP})
-    file(GENERATE OUTPUT ${OUTPUT}
-      INPUT ${TEMP}
-      CONDITION 1
-    )
-endmacro()
+set(ctest_file_base "${CMAKE_CURRENT_BINARY_DIR}/NUnit")
+set(ctest_include_file "${ctest_file_base}_include.cmake")
+set(ctest_tests_file "${ctest_file_base}_tests.cmake")
 
-foreach( lib SQLite::sqlite3 )
-  get_target_property(runtime_path ${lib} INTERFACE_RUNTIME_DIR)
-  set(PATH ${PATH} ${runtime_path})
-endforeach()
-
-file(GLOB SOURCES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cs")
-
-foreach(FILE ${SOURCES})
-  # Find all non-deprecated tests
-  file(STRINGS ${FILE} HasTests REGEX "\\[Test\\]")
-
-  LIST(LENGTH HasTests length)
-  if (${length} GREATER 0)
-    # Get the namespace
-    file(STRINGS ${FILE} NameSpaceLine REGEX "namespace Apache.Geode.Client.UnitTests")
-    string(REGEX REPLACE "namespace.*Apache" "Apache" NAMESPACE ${NameSpaceLine})
-
-    string(REGEX REPLACE "\\.cs" "" TEST ${FILE})
-    set(TESTS ${TESTS} ${TEST})
-    set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/.tests/${TEST})
-
-    # Get the test class (NewAPI tests have N in the file name but not test class name)
-    string(REGEX REPLACE "N$" "" TESTCLASS ${TEST})
-
-    set(TEST_SCRIPT ${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${TEST}.bat)
-    generate_config(${CMAKE_CURRENT_SOURCE_DIR}/test.bat.in ${CMAKE_CURRENT_BINARY_DIR}/.${TEST}.bat.in ${TEST_SCRIPT})
-
-    add_test(NAME ${TEST} COMMAND ${TEST_SCRIPT})
-    set_tests_properties(${TEST} PROPERTIES LABELS STABLE)
-
-    file(STRINGS ${FILE} IsDeprecated REGEX "\\[Category.*deprecated.*\\]")
-    if (IsDeprecated)
-      set_tests_properties(${TEST} PROPERTIES DISABLED TRUE)
-	  endif()
-  endif()
-endforeach()
-
-# Label any flaky tests here
-set_tests_properties(ThinClientCqStatusTestTwoServers
-    ThinClientPoolTestsN
-    ThinClientQueryTestsN
-  PROPERTIES
-    DISABLED TRUE
-    LABELS FLAKY
+add_custom_command(
+  TARGET Apache.Geode.Client.UnitTests POST_BUILD
+  BYPRODUCTS "${ctest_tests_file}"
+  COMMAND pwsh -File 
+          "$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}/NUnitTestAddTests.ps1>"
+          -AssemblyPath "$<SHELL_PATH:$<TARGET_FILE:Apache.Geode.Client.UnitTests>>"
+          -NUnitConsolePath "$<SHELL_PATH:${CMAKE_BINARY_DIR}/packages/NUnit.Runners.2.6.4/tools/nunit-console.exe>"
+          -WorkingDirectory "$<TARGET_FILE_DIR:Apache.Geode.Client.UnitTests>"
+          -CTestFile "$<SHELL_PATH:${ctest_tests_file}>"
+          -SourcePath "$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}>"
+          -ServerLogLevel "config"
+          -ServerSecurityLogLevel "config"
+          -ServerClasspath "$<SHELL_PATH:${CMAKE_BINARY_DIR}/tests/javaobject/javaobject.jar>"
+          -GeodePath "$<SHELL_PATH:${Geode_PATH}>"
+          -JavaPath "$<SHELL_PATH:${Java_JAVA_EXECUTABLE}>"
+          -EnvPath "$<SHELL_PATH:${CMAKE_BINARY_DIR}/packages/NUnit.Runners.2.6.4/tools>"
+  WORKING_DIRECTORY "$<TARGET_FILE_DIR:Apache.Geode.Client.UnitTests>"
 )
 
-# Label any tests that always fail here
-set_tests_properties(OverflowTestsN
-    ThinClientDeltaTestFailing
-    ThinClientDurableTestsN
-    ThinClientHARegionTestsN
-    ThinClientSecurityAuthTestsMUN
-    ThinClientSecurityAuthTestsN
-    RegionFailingTests
-    ThinClientSecurityAuthzTestsMUN
-    ThinClientSecurityAuthzTestsN
-  PROPERTIES
-    DISABLED TRUE
-    LABELS OMITTED
+file(WRITE "${ctest_include_file}"
+  "if(EXISTS \"${ctest_tests_file}\")\n"
+  "  include(\"${ctest_tests_file}\")\n"
+  "else()\n"
+  "  add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
+  "endif()\n"
+)
+
+set_property(DIRECTORY
+  APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
 )
 
 add_custom_target(run-stable-clicache-integration-tests
diff --git a/clicache/integration-test/CacheHelperN.cs b/clicache/integration-test/CacheHelperN.cs
index 2bc40bb..d97b708 100644
--- a/clicache/integration-test/CacheHelperN.cs
+++ b/clicache/integration-test/CacheHelperN.cs
@@ -317,7 +317,7 @@
     private const string LocatorStartArgs = "start locator --max-heap=512m";
     private const string LocatorStopArgs = "stop locator";
     private const int MaxWaitMillis = 60000;
-   
+
     private static string m_testDir = null;
     private static Dictionary<int, string> m_runningJavaServers =
       new Dictionary<int, string>();
@@ -463,7 +463,7 @@
 
     public static void ConnectConfig(string dsName, Properties<string, string> config)
     {
-        DSConnect(dsName, config);
+      DSConnect(dsName, config);
     }
 
     public static void Init()
@@ -471,12 +471,12 @@
       InitConfig(null, null);
     }
 
-		public static void InitConfig(Properties<string, string> config, IAuthInitialize authInitialize)
-		{
-			InitConfig(config, null, authInitialize);
-		}
+    public static void InitConfig(Properties<string, string> config, IAuthInitialize authInitialize)
+    {
+      InitConfig(config, null, authInitialize);
+    }
 
-		public static void InitConfig(Properties<string, string> config)
+    public static void InitConfig(Properties<string, string> config)
     {
       InitConfig(config, null);
     }
@@ -1686,7 +1686,7 @@
       m_gfeDir = Util.GetEnvironmentVariable("GFE_DIR");
       Assert.IsNotNull(m_gfeDir, "GFE_DIR is not set.");
       Assert.IsNotEmpty(m_gfeDir, "GFE_DIR is not set.");
-      gfsh = Path.Combine(m_gfeDir, "bin",  "gfsh.bat");
+      gfsh = Path.Combine(m_gfeDir, "bin", "gfsh.bat");
       m_gfeLogLevel = Util.GetEnvironmentVariable("GFE_LOGLEVEL");
       m_gfeSecLogLevel = Util.GetEnvironmentVariable("GFE_SECLOGLEVEL");
       if (m_gfeLogLevel == null || m_gfeLogLevel.Length == 0)
@@ -1714,12 +1714,12 @@
           string cacheXml = cacheXmls[i];
           Assert.IsNotNull(cacheXml, "cacheXml is not set for Java cacheserver.");
           Assert.IsNotEmpty(cacheXml, "cacheXml is not set for Java cacheserver.");
-          
+
           var duplicateFile = Path.Combine(MakeTempDirectory(), cacheXml);
           cacheXml = Path.Combine(Directory.GetCurrentDirectory(), cacheXml);
           createDuplicateXMLFile(cacheXml, duplicateFile);
           cacheXmls[i] = duplicateFile;
-        
+
           // Find the port number from the given cache.xml
           XmlDocument xmlDoc = new XmlDocument();
           xmlDoc.XmlResolver = null;
@@ -1819,7 +1819,7 @@
         {
           Assert.Fail("Locator property file creation failed: {0}: {1}", ex.GetType().Name, ex.Message);
         }
- 
+
         string locatorPort = " --port=" + getLocatorPort(locatorNum);
         if (extraLocatorArgs != null)
         {
@@ -1921,7 +1921,7 @@
           extraLocatorArgs = locatorPort;
         }
         string locatorArgs = LocatorStartArgs + " --name=" + locatorName + " --dir=" + startDir + extraLocatorArgs + " --http-service-port=0";
-        
+
         var exitCode = ExecuteGfsh(locatorArgs);
         if (0 != exitCode)
         {
@@ -2090,16 +2090,16 @@
 
     static string MakeTempDirectory()
     {
-       var tempDirectory = Path.Combine(tempDirectoryRoot, Path.GetRandomFileName());
-       Directory.CreateDirectory(tempDirectory);
-       return tempDirectory;
+      var tempDirectory = Path.Combine(tempDirectoryRoot, Path.GetRandomFileName());
+      Directory.CreateDirectory(tempDirectory);
+      return tempDirectory;
     }
 
     static int ExecuteGfsh(string command)
     {
       Util.Log("ExecuteGfsh: {0}", command);
 
-      using(var process = new Process())
+      using (var process = new Process())
       {
         process.StartInfo.FileName = gfsh;
         process.StartInfo.Arguments = command;
@@ -2132,9 +2132,13 @@
         Util.Log("ExecuteGfsh: Waiting for exit {0}", process.Id);
         if (!process.WaitForExit(MaxWaitMillis))
         {
+          Util.Log("ExecuteGfsh: Timeout, killing {0}", process.Id);
+
+          CloseAndIgnore(process.StandardOutput);
+          CloseAndIgnore(process.StandardError);
+
           try
           {
-            Util.Log("ExecuteGfsh: Timeout, killing {0}", process.Id);
             process.Kill();
           }
           catch (Exception)
@@ -2143,14 +2147,23 @@
           }
         }
 
-        //process.CancelOutputRead();
-        //process.CancelOutputRead();
-
         Util.Log("ExecuteGfsh: Exited {0}", process.Id);
         return process.ExitCode;
       }
     }
 
+    public static void CloseAndIgnore(StreamReader streamRead)
+    {
+      try
+      {
+        streamRead.Close();
+      } 
+      catch (Exception)
+      {
+        // ignored
+      }
+    }
+
     public static void StopJavaLocator(int locatorNum)
     {
       StopJavaLocator(locatorNum, true, false);
diff --git a/clicache/integration-test/CacheServerMsgs.cs b/clicache/integration-test/CacheServerMsgs.cs
deleted file mode 100644
index 076e59a..0000000
--- a/clicache/integration-test/CacheServerMsgs.cs
+++ /dev/null
@@ -1,58 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  [Category("unicast_only")]
-  public class CacheServerMsgs : UnitTests
-  {
-    Cache m_cache = null;
-
-    protected override ClientBase[] GetClients()
-    {
-      return null;
-    }
-
-    [TestFixtureSetUp]
-    public override void InitTests()
-    {
-      base.InitTests();
-      CacheHelper.InitConfig("MessagesTest", "theCache", "SERVER", null,
-        null, null);
-      m_cache = CacheHelper.DCache;
-    }
-
-    [TestFixtureTearDown]
-    public override void EndTests()
-    {
-      try
-      {
-        CacheHelper.Close();
-      }
-      finally
-      {
-        base.EndTests();
-      }
-    }
-  }
-}
diff --git a/clicache/integration-test/CacheableWrapper.cs b/clicache/integration-test/CacheableWrapper.cs
deleted file mode 100644
index cac4e42..0000000
--- a/clicache/integration-test/CacheableWrapper.cs
+++ /dev/null
@@ -1,208 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Collections;
-using System.Runtime.Serialization;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-
-  /// <summary>
-  /// Interface class for wrappers of geode cacheable types.
-  /// </summary>
-  /// <remarks>
-  /// This interface has various useful functions like setting value randomly,
-  /// and finding checksum.
-  /// </remarks>
-  public abstract class CacheableWrapper
-  {
-    #region Protected members
-
-    protected ISerializable m_cacheableObject = null;
-    protected uint m_typeId;
-
-    #endregion
-
-    public virtual ISerializable Cacheable
-    {
-      get
-      {
-        return m_cacheableObject;
-      }
-    }
-
-    public uint TypeId
-    {
-      get
-      {
-        return m_typeId;
-      }
-      set
-      {
-        m_typeId = value;
-      }
-    }
-
-    public abstract void InitRandomValue(int maxSize);
-
-    public abstract uint GetChecksum(ISerializable cacheableObject);
-
-    public virtual uint GetChecksum()
-    {
-      return GetChecksum(m_cacheableObject);
-    }
-  }
-
-  /// <summary>
-  /// Interface class for wrappers of geode cacheable key types.
-  /// </summary>
-  /// <remarks>
-  /// This interface has various useful functions like setting value randomly,
-  /// and finding checksum, initializing key etc.
-  /// </remarks>
-  public abstract class CacheableKeyWrapper : CacheableWrapper
-  {
-    public override ISerializable Cacheable
-    {
-      get
-      {
-        return m_cacheableObject;
-      }
-    }
-
-    public virtual ICacheableKey CacheableKey
-    {
-      get
-      {
-        return (ICacheableKey)m_cacheableObject;
-      }
-    }
-
-    public abstract int MaxKeys
-    {
-      get;
-    }
-
-    public abstract void InitKey(int keyIndex, int maxSize);
-  }
-
-  public delegate CacheableWrapper CacheableWrapperDelegate();
-  public delegate CacheableKeyWrapper CacheableKeyWrapperDelegate();
-
-  /// <summary>
-  /// Factory class to create <c>CacheableWrapper</c> objects.
-  /// </summary>
-  public static class CacheableWrapperFactory
-  {
-    #region Private members
-
-    private static Dictionary<UInt32, CacheableKeyWrapperDelegate>
-      m_registeredKeyTypeIdMap =
-      new Dictionary<UInt32, CacheableKeyWrapperDelegate>();
-    private static Dictionary<UInt32, Delegate>
-      m_registeredValueTypeIdMap = new Dictionary<UInt32, Delegate>();
-    private static Dictionary<UInt32, Type>
-      m_typeIdNameMap = new Dictionary<UInt32, Type>();
-
-    #endregion
-
-    #region Public methods
-
-    public static CacheableWrapper CreateInstance(UInt32 typeId)
-    {
-      Delegate wrapperDelegate;
-      lock (((ICollection)m_registeredValueTypeIdMap).SyncRoot)
-      {
-        if (m_registeredValueTypeIdMap.TryGetValue(typeId,
-          out wrapperDelegate))
-        {
-          CacheableWrapper wrapper =
-            (CacheableWrapper)wrapperDelegate.DynamicInvoke(null);
-          wrapper.TypeId = typeId;
-          return wrapper;
-        }
-      }
-      return null;
-    }
-
-    public static CacheableKeyWrapper CreateKeyInstance(UInt32 typeId)
-    {
-      CacheableKeyWrapperDelegate wrapperDelegate;
-      lock (((ICollection)m_registeredKeyTypeIdMap).SyncRoot)
-      {
-        if (m_registeredKeyTypeIdMap.TryGetValue(typeId,
-          out wrapperDelegate))
-        {
-          CacheableKeyWrapper wrapper = wrapperDelegate();
-          wrapper.TypeId = typeId;
-          return wrapper;
-        }
-      }
-      return null;
-    }
-
-    public static void RegisterType(UInt32 typeId,
-      Type type, CacheableWrapperDelegate wrapperDelegate)
-    {
-      m_registeredValueTypeIdMap[typeId] = wrapperDelegate;
-      m_typeIdNameMap[typeId] = type;
-    }
-
-    public static void RegisterKeyType(UInt32 typeId,
-      Type type, CacheableKeyWrapperDelegate wrapperDelegate)
-    {
-      m_registeredKeyTypeIdMap[typeId] = wrapperDelegate;
-      m_registeredValueTypeIdMap[typeId] = wrapperDelegate;
-      m_typeIdNameMap[typeId] = type;
-    }
-
-    public static void ClearStatics()
-    {
-      m_registeredKeyTypeIdMap.Clear();
-      m_registeredValueTypeIdMap.Clear();
-      m_typeIdNameMap.Clear();
-    }
-
-    public static Type GetTypeForId(UInt32 typeId)
-    {
-      Type type;
-      lock (((ICollection)m_typeIdNameMap).SyncRoot)
-      {
-        if (m_typeIdNameMap.TryGetValue(typeId, out type))
-        {
-          return type;
-        }
-      }
-      return null;
-    }
-
-    public static ICollection<UInt32> GetRegisteredKeyTypeIds()
-    {
-      return m_registeredKeyTypeIdMap.Keys;
-    }
-
-    public static ICollection<UInt32> GetRegisteredValueTypeIds()
-    {
-      return m_registeredValueTypeIdMap.Keys;
-    }
-
-    #endregion
-  }
-}
diff --git a/clicache/integration-test/DataIOTests.cs b/clicache/integration-test/DataIOTests.cs
deleted file mode 100644
index d4488e5..0000000
--- a/clicache/integration-test/DataIOTests.cs
+++ /dev/null
@@ -1,241 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  [Category("unicast_only")]
-  public class DataIOTests : UnitTests
-  {
-    XmlNodeReaderWriter settings = Util.DefaultSettings;
-
-    protected override ClientBase[] GetClients()
-    {
-      return null;
-    }
-
-    [Test]
-    public void Byte()
-    {
-      List<Dictionary<string, string>> testbytes = settings.GetValues(MethodBase.GetCurrentMethod(), "byte");
-      if (testbytes != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testbytes)
-        {
-          DataOutput dataOutput = new DataOutput();
-          byte testbyte = Util.String2Byte(dEntry["value"]);
-          dataOutput.WriteByte(testbyte);
-          byte[] buffer = dataOutput.GetBuffer();
-          Assert.AreEqual(testbyte, buffer[0]);
-
-          DataInput dataInput = new DataInput(buffer);
-          byte result = dataInput.ReadByte();
-          Assert.AreEqual(testbyte, result);
-        }
-      }
-    }
-
-    [Test]
-    public void Boolean()
-    {
-      List<Dictionary<string, string>> testbools = settings.GetValues(MethodBase.GetCurrentMethod(), "bool");
-      if (testbools != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testbools)
-        {
-          DataOutput dataOutput = new DataOutput();
-          bool testbool = bool.Parse(dEntry["value"]);
-          dataOutput.WriteBoolean(testbool);
-          byte[] buffer = dataOutput.GetBuffer();
-          byte[] expectedBytes = Util.String2Bytes(dEntry["bytes"]);
-          Util.CompareTestArrays(expectedBytes, buffer);
-
-          DataInput dataInput = new DataInput(buffer);
-          bool result = dataInput.ReadBoolean();
-          Assert.AreEqual(testbool, result);
-        }
-      }
-    }
-
-    [Test]
-    public void Int16()
-    {
-      List<Dictionary<string, string>> testshorts = settings.GetValues(MethodBase.GetCurrentMethod(), "short");
-      if (testshorts != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testshorts)
-        {
-          DataOutput dataOutput = new DataOutput();
-          short testshort = Util.String2Int16(dEntry["value"]);
-          dataOutput.WriteInt16(testshort);
-          byte[] buffer = dataOutput.GetBuffer();
-          byte[] expectedBytes = Util.String2Bytes(dEntry["bytes"]);
-          Util.CompareTestArrays(expectedBytes, buffer);
-
-          DataInput dataInput = new DataInput(buffer);
-          short result = dataInput.ReadInt16();
-          Assert.AreEqual(testshort, result);
-        }
-      }
-    }
-
-    [Test]
-    public void Int32()
-    {
-      List<Dictionary<string, string>> testints = settings.GetValues(MethodBase.GetCurrentMethod(), "int");
-      if (testints != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testints)
-        {
-          DataOutput dataOutput = new DataOutput();
-          int testint = Util.String2Int32(dEntry["value"]);
-          dataOutput.WriteInt32(testint);
-          byte[] buffer = dataOutput.GetBuffer();
-          byte[] expectedBytes = Util.String2Bytes(dEntry["bytes"]);
-          Util.CompareTestArrays(expectedBytes, buffer);
-
-          DataInput dataInput = new DataInput(buffer);
-          int result = dataInput.ReadInt32();
-          Assert.AreEqual(testint, result);
-        }
-      }
-    }
-
-    [Test]
-    public void Int64()
-    {
-      List<Dictionary<string, string>> testints = settings.GetValues(MethodBase.GetCurrentMethod(), "int");
-      if (testints != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testints)
-        {
-          DataOutput dataOutput = new DataOutput();
-          long testlong = Util.String2Int64(dEntry["value"]);
-          dataOutput.WriteInt64(testlong);
-          byte[] buffer = dataOutput.GetBuffer();
-          byte[] expectedBytes = Util.String2Bytes(dEntry["bytes"]);
-          Util.CompareTestArrays(expectedBytes, buffer);
-
-          DataInput dataInput = new DataInput(buffer);
-          long result = dataInput.ReadInt64();
-          Assert.AreEqual(testlong, result);
-        }
-      }
-    }
-
-    [Test]
-    public void Float()
-    {
-      List<Dictionary<string, string>> testfloats = settings.GetValues(MethodBase.GetCurrentMethod(), "float");
-      if (testfloats != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testfloats)
-        {
-          DataOutput dataOutput = new DataOutput();
-          float testfloat = float.Parse(dEntry["value"]);
-          dataOutput.WriteFloat(testfloat);
-          byte[] buffer = dataOutput.GetBuffer();
-          byte[] expectedBytes = Util.String2Bytes(dEntry["bytes"]);
-          Util.CompareTestArrays(expectedBytes, buffer);
-
-          DataInput dataInput = new DataInput(buffer);
-          float result = dataInput.ReadFloat();
-          Assert.AreEqual(testfloat, result);
-        }
-      }
-    }
-
-    [Test]
-    public void Double()
-    {
-      List<Dictionary<string, string>> testdoubles = settings.GetValues(MethodBase.GetCurrentMethod(), "double");
-      if (testdoubles != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testdoubles)
-        {
-          DataOutput dataOutput = new DataOutput();
-          double testdouble = double.Parse(dEntry["value"]);
-          dataOutput.WriteDouble(testdouble);
-          byte[] buffer = dataOutput.GetBuffer();
-          byte[] expectedBytes = Util.String2Bytes(dEntry["bytes"]);
-          Util.CompareTestArrays(expectedBytes, buffer);
-
-          DataInput dataInput = new DataInput(buffer);
-          double result = dataInput.ReadDouble();
-          Assert.AreEqual(testdouble, result);
-        }
-      }
-    }
-
-    [Test]
-    public void ASCIIString()
-    {
-      List<Dictionary<string, string>> testasciis = settings.GetValues(MethodBase.GetCurrentMethod(), "ascii");
-      if (testasciis != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testasciis)
-        {
-          DataOutput dataOutput = new DataOutput();
-          string testascii = dEntry["value"];
-          dataOutput.WriteUTF(testascii);
-          byte[] buffer = dataOutput.GetBuffer();
-          Assert.AreEqual(Util.String2Byte(dEntry["byte0"]), buffer[0]);
-          Assert.AreEqual(Util.String2Byte(dEntry["byte1"]), buffer[1]);
-          for (int i = 0; i < testascii.Length; i++)
-          {
-            Assert.AreEqual(testascii[i], buffer[i + 2]);
-          }
-
-          DataInput dataInput = new DataInput(buffer);
-          string result = dataInput.ReadUTF();
-          Assert.AreEqual(testascii.Length, result.Length);
-          Assert.AreEqual(testascii, result);
-        }
-      }
-    }
-
-    [Test]
-    public void UTFString()
-    {
-      List<Dictionary<string, string>> testutfs = settings.GetValues(MethodBase.GetCurrentMethod(), "utf");
-      if (testutfs != null)
-      {
-        foreach (Dictionary<string, string> dEntry in testutfs)
-        {
-          DataOutput dataOutput = new DataOutput();
-          string testutf = Util.String2String(dEntry["value"]);
-          dataOutput.WriteUTF(testutf);
-          byte[] buffer = dataOutput.GetBuffer();
-          byte[] expectedBytes = Util.String2Bytes(dEntry["bytes"]);
-          Util.CompareTestArrays(expectedBytes, buffer);
-
-          DataInput dataInput = new DataInput(buffer);
-          string result = dataInput.ReadUTF();
-          Assert.AreEqual(testutf.Length, result.Length);
-          Assert.AreEqual(testutf, result);
-        }
-      }
-    }
-  }
-}
diff --git a/clicache/integration-test/DistGetTests.cs b/clicache/integration-test/DistGetTests.cs
deleted file mode 100644
index ce680bb..0000000
--- a/clicache/integration-test/DistGetTests.cs
+++ /dev/null
@@ -1,191 +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.
- */
-
-using System;
-using System.Threading;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  public class DistGetTests : UnitTests
-  {
-    private const string RootRegion = "DistGet";
-    private const string SomeDistRegion = "SomeDistReg";
-    private const string GetRegion = "GetWithInvalid";
-    private const string GetILRegion = "GetWithInvalid_IL";
-
-    private const int InvBeginKey = 2006;
-    private const int InvEndKey = 2260;
-    private const int Inv2BeginKey = 4006;
-    private const int Inv2EndKey = 4260;
-
-    private Region m_region;
-    private UnitProcess m_dataHolder, m_getter, m_invalidOne, m_invalidTwo;
-
-    protected override ClientBase[] GetClients()
-    {
-      m_dataHolder = new UnitProcess();
-      m_getter = new UnitProcess();
-      m_invalidOne = new UnitProcess();
-      m_invalidTwo = new UnitProcess();
-      return new ClientBase[] { m_dataHolder, m_getter, m_invalidOne, m_invalidTwo };
-    }
-
-    #region Functions used by the tests
-
-    public void Puts()
-    {
-      m_region = CacheHelper.CreateDistRegion(RootRegion,
-        ScopeType.DistributedAck, SomeDistRegion, 10);
-      Util.Log("Beginning puts.");
-      m_region.Put("findme", "hello");
-
-      CacheableString cRes = m_region.Get("findme") as CacheableString;
-      Assert.AreEqual("hello", cRes.Value);
-    }
-
-    public void FindItems()
-    {
-      m_region = CacheHelper.CreateDistRegion(RootRegion,
-        ScopeType.DistributedAck, SomeDistRegion, 10);
-
-      Util.Log("Created second process region.");
-
-      CacheableString cKey = new CacheableString("findme");
-      CacheableString cRes = m_region.Get(cKey) as CacheableString;
-      Assert.AreEqual("hello", cRes.Value);
-      Util.Log("Received value for findme: {0}", cRes.Value);
-
-      m_region.LocalInvalidateRegion();
-      Util.Log("invalidated region");
-      Assert.IsTrue(m_region.ContainsKey(cKey));
-      Assert.IsFalse(m_region.ContainsValueForKey(cKey));
-      Util.Log("passed invalid assertions.");
-
-      cRes = m_region.Get(cKey) as CacheableString;
-      Util.Log("get completed.");
-      Assert.AreEqual("hello", cRes.Value);
-      Util.Log("Received value for findme: {0}", cRes.Value);
-    }
-
-    public void MakeDataTwo(string regionName)
-    {
-      m_region = CacheHelper.CreateILRegion(regionName, true, true, null);
-      CacheableInt32 cKey;
-      for (int i = InvBeginKey; i <= InvEndKey; i++)
-      {
-        cKey = new CacheableInt32(i);
-        m_region.Put(cKey, cKey);
-      }
-    }
-
-    public void Join(string regionName)
-    {
-      m_region = CacheHelper.CreateILRegion(regionName, true, true, null);
-      CacheableInt32 cVal;
-      for (int i = InvBeginKey; i <= InvEndKey; i++)
-      {
-        cVal = m_region.Get(i) as CacheableInt32;
-        Assert.IsNotNull(cVal);
-        Assert.AreEqual(i, cVal.Value);
-      }
-      m_region.LocalInvalidateRegion();
-    }
-
-    public void CheckNotValid(string regionName)
-    {
-      m_region = CacheHelper.CreateILRegion(regionName, true, true, null);
-      CacheableInt32 cVal;
-      for (int i = InvBeginKey; i <= InvEndKey; i++)
-      {
-        cVal = m_region.Get(i) as CacheableInt32;
-        Assert.IsNotNull(cVal);
-        Assert.AreEqual(i, cVal.Value);
-      }
-      for (int i = InvBeginKey; i <= InvEndKey; i++)
-      {
-        m_region.Put(i, -i);
-      }
-      for (int i = InvBeginKey; i <= InvEndKey; i++)
-      {
-        cVal = m_region.Get(i) as CacheableInt32;
-        Assert.IsNotNull(cVal);
-        Assert.AreEqual(-i, cVal.Value);
-      }
-    }
-
-    public void PutKeys(int start, int end, int factor, bool invalidate)
-    {
-      for (int i = start; i <= end; i++)
-      {
-        m_region.Put(i, i * factor);
-        if (invalidate)
-        {
-          m_region.LocalInvalidate(i);
-        }
-      }
-    }
-
-    public void CheckKeys(int start, int end, int factor, bool invalidate, bool netSearch)
-    {
-      CacheableInt32 cKey, cVal;
-      for (int i = start; i <= end; i++)
-      {
-        cKey = new CacheableInt32(i);
-        if (netSearch)
-        {
-          Assert.IsFalse(m_region.ContainsKey(cKey));
-        }
-        else
-        {
-          Assert.IsTrue(m_region.ContainsValueForKey(cKey));
-        }
-        cVal = m_region.Get(cKey) as CacheableInt32;
-        Assert.IsNotNull(cVal);
-        Assert.AreEqual(i * factor, cVal.Value);
-        if (invalidate)
-        {
-          m_region.LocalInvalidate(cKey);
-        }
-      }
-    }
-
-    #endregion
-
-    [Test]
-    public void DistReg()
-    {
-      m_dataHolder.Call(Puts);
-      m_getter.Call(FindItems);
-    }
-
-    [Test]
-    public void GetWithInvalid()
-    {
-      m_dataHolder.Call(MakeDataTwo, GetRegion);
-      m_invalidOne.Call(Join, GetRegion);
-      m_invalidTwo.Call(Join, GetRegion);
-      m_getter.Call(CheckNotValid, GetRegion);
-
-      m_invalidTwo.Call(CheckKeys, InvBeginKey, InvEndKey, -1, false, false);
-      m_invalidOne.Call(CheckKeys, InvBeginKey, InvEndKey, -1, false, false);
-    }
-  }
-}
diff --git a/clicache/integration-test/DistOpsTests.cs b/clicache/integration-test/DistOpsTests.cs
deleted file mode 100644
index ae6ac4c..0000000
--- a/clicache/integration-test/DistOpsTests.cs
+++ /dev/null
@@ -1,85 +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.
- */
-
-using System;
-using System.Threading;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  public class DistOpsTests : DistOpsSteps
-  {
-    #region Private statics/constants and members
-
-    private static string[] AckRegionNames = { "DistRegionAck1", "DistRegionNoAck1" };
-    private static string[] ILRegionNames = { "IL_DistRegionAck", "IL_DistRegionNoAck" };
-
-    private UnitProcess m_client1, m_client2, m_client3;
-
-    #endregion
-
-    protected override ClientBase[] GetClients()
-    {
-      m_client1 = new UnitProcess();
-      m_client2 = new UnitProcess();
-      m_client3 = new UnitProcess();
-      return new ClientBase[] { m_client1, m_client2, m_client3 };
-    }
- 
-    [Test]
-    public void DistOps()
-    {
-      m_client1.Call(CreateRegions, AckRegionNames);
-      Util.Log("StepOne complete.");
-
-      m_client2.Call(CreateRegions, AckRegionNames);
-      Util.Log("StepTwo complete.");
-
-      m_client1.Call(StepThree);
-      Util.Log("StepThree complete.");
-
-      m_client2.Call(StepFour);
-      Util.Log("StepFour complete.");
-
-      m_client1.Call(StepFive, true);
-      Util.Log("StepFive complete.");
-
-      Util.Log("StepSix commencing.");
-      m_client2.Call(StepSix, true);
-      Util.Log("StepSix complete.");
-
-      m_client1.Call(StepSeven);
-      Util.Log("StepSeven complete.");
-
-      m_client2.Call(StepEight);
-      Util.Log("StepEight complete.");
-
-      m_client1.Call(StepNine);
-      Util.Log("StepNine complete.");
-
-      m_client2.Call(StepTen);
-      Util.Log("StepTen complete.");
-
-      m_client1.Call(StepEleven);
-      Util.Log("StepEleven complete.");
-    }
-
-  }
-}
diff --git a/clicache/integration-test/DistributedSystemTests.cs b/clicache/integration-test/DistributedSystemTests.cs
deleted file mode 100644
index 157eee2..0000000
--- a/clicache/integration-test/DistributedSystemTests.cs
+++ /dev/null
@@ -1,136 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  [Category("unicast_only")]
-  public class DistributedSystemTests : UnitTests
-  {
-    protected override ClientBase[] GetClients()
-    {
-      return null;
-    }
-
-    [Test]
-    public void Connect()
-    {
-      try
-      {
-        DistributedSystem.Disconnect(CacheHelper.getCache());
-        Assert.Fail("NotConnectedException should have occurred when "
-          + "disconnecting without having connected.");
-      }
-      catch (NotConnectedException ex)
-      {
-        Util.Log("Got an expected exception in DistributedSystem.disconnect: "
-          + ex);
-      }
-      try
-      {
-        CacheHelper.ConnectName("ConnTest");
-      }
-      finally
-      {
-        CacheHelper.Close();
-      }
-    }
-
-    [Test]
-    public void ConnectToNull()
-    {
-      Util.Log("Creating DistributedSytem with null name...");
-      try
-      {
-        CacheHelper.ConnectName(null);
-        CacheHelper.Close();
-        Assert.Fail("IllegalArgumentException should have occurred when "
-          + "connecting to a null DistributedSystem.");
-      }
-      catch (IllegalArgumentException ex)
-      {
-        Util.Log("Got an expected exception in DistributedSystem.connect: "
-          + ex);
-      }
-    }
-
-    [Test]
-    public void Reconnect()
-    {
-      string[] memberTypes = { "PEER", "SERVER" };
-      foreach (string memberType in memberTypes)
-      {
-        // Connect and disconnect 10 times
-
-        for (int i = 0; i < 10; i++)
-        {
-          CacheHelper.InitConfig(memberType, null);
-
-          try
-          {
-            Region region1 = CacheHelper.CreatePlainRegion("R1");
-            Region region2 = CacheHelper.CreatePlainRegion("R2");
-          }
-          finally
-          {
-            CacheHelper.Close();
-          }
-        }
-      }
-    }
-
-    [Test]
-    public void Example()
-    {
-      CacheableString cVal;
-
-      Region region = CacheHelper.CreateLRURegion("exampleRegion",
-        1000, ScopeType.DistributedNoAck);
-      try
-      {
-        // put some values into the cache.
-        for (int i = 1; i <= 2000; i++)
-        {
-          region.Put("key-" + i, "value-" + i);
-        }
-
-        // do some gets... printing what we find in the cache.
-        for (int i = 1; i <= 2000; i += 100)
-        {
-          cVal = region.Get("key-" + i) as CacheableString;
-          if (cVal == null)
-          {
-            Util.Log("Didn't find key-{0} in the cache.", i);
-          }
-          else
-          {
-            Util.Log("Found key-{0} with value {1}.", i, cVal.Value);
-          }
-        }
-      }
-      finally
-      {
-        CacheHelper.Close();
-      }
-    }
-  }
-}
diff --git a/clicache/integration-test/LogTests.cs b/clicache/integration-test/LogTests.cs
index 45f2ec8..4eca1d1 100644
--- a/clicache/integration-test/LogTests.cs
+++ b/clicache/integration-test/LogTests.cs
@@ -23,7 +23,7 @@
   using NUnit.Framework;
   using Apache.Geode.DUnitFramework;
 
-
+  [Ignore("broken")]
   [TestFixture]
   [Category("unicast_only")]
   public class LogTests : UnitTests
diff --git a/clicache/integration-test/NUnitTestAddTests.ps1 b/clicache/integration-test/NUnitTestAddTests.ps1
new file mode 100644
index 0000000..b82e816
--- /dev/null
+++ b/clicache/integration-test/NUnitTestAddTests.ps1
@@ -0,0 +1,82 @@
+# 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.
+
+Param
+(
+    [Parameter(Mandatory)]
+    [string]$AssemblyPath,
+    [Parameter(Mandatory)]
+    [string]$NUnitConsolePath,
+    [Parameter(Mandatory)]
+    [string]$WorkingDirectory,
+    [Parameter(Mandatory)]
+    [string]$CTestFile,
+    [Parameter(Mandatory)]
+    [string]$SourcePath,
+    [Parameter(Mandatory)]
+    [string]$ServerLogLevel,
+    [Parameter(Mandatory)]
+    [string]$ServerSecurityLogLevel,
+    [Parameter(Mandatory)]
+    [string]$ServerClasspath,
+    [Parameter(Mandatory)]
+    [string]$GeodePath,
+    [Parameter(Mandatory)]
+    [string]$JavaPath,
+    [Parameter(Mandatory = $FALSE)]
+    [string]$EnvPath
+)
+
+#$ErrorActionPreference = "Stop
+
+Remove-Item -Path $CTestFile -Force -ErrorAction Ignore 
+
+$nunit = [reflection.assembly]::LoadFrom("nunit.Framework.dll")
+
+$assembly = [reflection.assembly]::LoadFrom($AssemblyPath)
+
+foreach ($type in $assembly.GetTypes())
+{
+    $ignoreFixture = $FALSE;
+
+    foreach ($customAttribute in $type.CustomAttributes)
+    {
+        if ($customAttribute.AttributeType.Equals([NUnit.Framework.IgnoreAttribute]))
+        {
+            $ignoreFixture = $TRUE
+        }
+    }
+
+    foreach ($method in $type.GetMethods())
+    {
+        foreach ($customAttribute in $method.CustomAttributes)
+        {
+            if ($customAttribute.AttributeType.Equals([NUnit.Framework.TestAttribute]))
+            {
+                $testName = "$($method.ReflectedType.NameSpace).$($method.ReflectedType.Name).$($method.Name)"
+                Add-Content -Path $CTestFile -Value "add_test( $testName [==[$NUnitConsolePath]==] /run:$testName [==[$AssemblyPath]==])"
+                Add-Content -Path $CTestFile -Value "set_tests_properties( $testName PROPERTIES `
+                        WORKING_DIRECTORY [==[$WorkingDirectory]==] `
+                        ENVIRONMENT [==[TESTSRC=$SourcePath;GFE_LOGLEVEL=$ServerLogLevel;GFE_SECLOGLEVEL=$ServerSecurityLogLevel;GF_JAVA=$JavaPath;GFE_DIR=$GeodePath;GF_CLASSPATH=$ServerClasspath;PATH=$EnvPath]==] `
+                        )"
+                if ($ignoreFixture -or $customAttribute.AttributeType.Equals([NUnit.Framework.IgnoreAttribute]))
+                {
+                    Add-Content -Path $CTestFile -Value "set_tests_properties( $testName PROPERTIES DISABLED True )"
+                }
+            }
+        }
+    }
+}
+
diff --git a/clicache/integration-test/NetTests.cs b/clicache/integration-test/NetTests.cs
deleted file mode 100644
index d667dc4..0000000
--- a/clicache/integration-test/NetTests.cs
+++ /dev/null
@@ -1,173 +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.
- */
-
-using System;
-using System.Threading;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  public class NetTests : UnitTests
-  {
-    private const string TestRegion = "TestRegion";
-    private const string TestRegionWrite = "TestRegionWrite";
-    private const int NumEntries = 200;
-
-    private Region m_region;
-    private Region m_netWriteRegion;
-
-    private TallyLoader m_ldr = new TallyLoader();
-    private TallyWriter m_lwr = new TallyWriter();
-
-    private UnitProcess m_client1, m_client2, m_client3;
-
-    protected override ClientBase[] GetClients()
-    {
-      m_client1 = new UnitProcess();
-      m_client2 = new UnitProcess();
-      m_client3 = new UnitProcess();
-      return new ClientBase[] { m_client1, m_client2, m_client3 };
-    }
-
-    #region Functions invoked by the tests
-
-    public void DoGets(Region region, int num)
-    {
-      for(int i = 0; i < num; i++)
-      {
-        CacheableInt32 val = region.Get(i) as CacheableInt32;
-        Assert.AreEqual(i, val.Value);
-      }
-    }
-
-    public void CreateRegionWithTallyLoader(ScopeType scope)
-    {
-      var regionAttributesFactory = new RegionAttributesFactory();
-      regionAttributesFactory.SetCacheLoader(m_ldr);
-      regionAttributesFactory.SetScope(scope);
-      regionAttributesFactory.SetCachingEnabled(true);
-
-      m_region = CacheHelper.CreateRegion(TestRegion,
-        regionAttributesFactory.Create());
-    }
-
-    public void CreateRegionAndGetNEntries(int num)
-    {
-      CacheHelper.CreateDistribRegion(TestRegion, false, true);
-      m_region = CacheHelper.GetVerifyRegion(TestRegion);
-      DoGets(m_region, num);
-      ISerializable[] arr = m_region.GetKeys();
-      Assert.AreEqual(num, arr.Length);
-    }
-
-    public void VerifyLoaderCallsAfterGets(int num)
-    {
-      Assert.AreEqual(num, m_ldr.Loads);
-      Util.Log("Calling doGets for verify");
-      //Thread.Sleep(2000);
-      //doGets(m_region, load);
-      ISerializable[] arr = m_region.GetKeys();
-      Assert.AreEqual(num, arr.Length);
-    }
-
-    public void RegionThreeLoadEntries(int num)
-    {
-      var regionAttributesFactory = new RegionAttributesFactory();
-      regionAttributesFactory.SetScope(ScopeType.Local);
-      regionAttributesFactory.SetCacheLoader(m_ldr);
-      m_region = CacheHelper.CreateRegion(TestRegion, regionAttributesFactory.Create());
-      m_ldr.Reset();
-      Thread.Sleep(100);
-      DoGets(m_region, num);
-      Assert.AreEqual(num, m_ldr.Loads);
-      ISerializable[] arr = m_region.GetKeys();
-      Assert.AreEqual(num, arr.Length);
-    }
-
-    public void CreateRegionWithTallyWriter(ScopeType scope)
-    {
-      var regionAttributesFactory = new RegionAttributesFactory();
-      regionAttributesFactory.SetCacheWriter(m_lwr);
-      regionAttributesFactory.SetScope(scope);
-      regionAttributesFactory.SetCachingEnabled(true);
-
-      m_netWriteRegion = CacheHelper.CreateRegion(TestRegionWrite,
-        regionAttributesFactory.Create());
-    }
-
-    public void RegionTwoCreateEntries(int num)
-    {
-      CacheHelper.CreateDistribRegion(TestRegionWrite, false, true);
-      m_netWriteRegion = CacheHelper.GetVerifyRegion(TestRegionWrite);
-      Thread.Sleep(100);
-      TestCreateEntryActions(num);
-    }
-
-    public void TestCreateEntryActions(int num)
-    {
-      for (int i = 0; i < num; i++)
-      {
-        CacheableInt32 key = new CacheableInt32(i);
-        m_netWriteRegion.Put(key, key);
-      }
-    }
-
-    public void TestUpdateActions(int num)
-    {
-      for (int i = 0; i < num; i++)
-      {
-        CacheableInt32 key = new CacheableInt32(i);
-        m_netWriteRegion.Put(key, key);
-      }
-    }
-
-    public void VerifyWriterCallsAfterCreate(int num)
-    {
-      Assert.AreEqual(num, m_lwr.Creates);
-    }
-
-    public void VerifyWriterCallsAfterUpdates(int num)
-    {
-      Assert.AreEqual(num, m_lwr.Creates);
-      Assert.AreEqual(num, m_lwr.Updates);
-    }
-
-    #endregion
-
-    [Test]
-    public void LoaderTest()
-    {
-      m_client1.Call(CreateRegionWithTallyLoader, ScopeType.DistributedNoAck);
-      m_client2.Call(CreateRegionAndGetNEntries, NumEntries);
-      m_client1.Call(VerifyLoaderCallsAfterGets, NumEntries);
-      m_client3.Call(RegionThreeLoadEntries, NumEntries);
-    }
-
-    [Test]
-    public void WriterTest()
-    {
-      m_client1.Call(CreateRegionWithTallyWriter, ScopeType.DistributedNoAck);
-      m_client2.Call(RegionTwoCreateEntries, NumEntries);
-      m_client1.Call(VerifyWriterCallsAfterCreate, NumEntries);
-      m_client2.Call(TestUpdateActions, NumEntries);
-      m_client1.Call(VerifyWriterCallsAfterUpdates, NumEntries);
-    }
-  }
-}
diff --git a/clicache/integration-test/OverflowTestsN.cs b/clicache/integration-test/OverflowTestsN.cs
index f82dddb..ea3b86c 100644
--- a/clicache/integration-test/OverflowTestsN.cs
+++ b/clicache/integration-test/OverflowTestsN.cs
@@ -29,6 +29,7 @@
   using Apache.Geode.DUnitFramework;
   using Apache.Geode.Client;
 
+  [Ignore("broken")]
   [TestFixture]
   [Category("group4")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/PutGetPerfTests.cs b/clicache/integration-test/PutGetPerfTests.cs
deleted file mode 100644
index 606df48..0000000
--- a/clicache/integration-test/PutGetPerfTests.cs
+++ /dev/null
@@ -1,333 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  public class PutGetPerfTests : UnitTests
-  {
-    #region Constants
-
-    private const int MaxKeys = 25000;
-    private const bool Mirrored = false;
-
-    #endregion
-
-    private CacheableString[] keysA = null;
-    private CacheableString[] keysB = null;
-    private CacheableString[] valuesA = null;
-    private CacheableString[] valuesB = null;
-
-    private CacheableInt32[] intKeysA = null;
-    private CacheableInt32[] intKeysB = null;
-    private CacheableInt32[] intValuesA = null;
-    private CacheableInt32[] intValuesB = null;
-
-    private UnitProcess m_client1, m_client2, m_client3, m_client4;
-
-    protected override ClientBase[] GetClients()
-    {
-      m_client1 = new UnitProcess();
-      m_client2 = new UnitProcess();
-      m_client3 = new UnitProcess();
-      m_client4 = new UnitProcess();
-      return new ClientBase[] { m_client1, m_client2, m_client3, m_client4 };
-    }
-
-    #region Private functions
-
-    private void InitStringObjects(int num, string prefix,
-      ref CacheableString[] strings)
-    {
-      if (num > 0)
-      {
-        strings = new CacheableString[num];
-        for (int i = 1; i <= num; i++)
-        {
-          strings[i - 1] = new CacheableString(prefix + i.ToString());
-        }
-      }
-    }
-
-    private void InitIntObjects(int num, int offset, int factor,
-      ref CacheableInt32[] ints)
-    {
-      if (num > 0)
-      {
-        ints = new CacheableInt32[num];
-        for (int i = 1; i <= num; i++)
-        {
-          ints[i - 1] = new CacheableInt32(offset + i * factor);
-        }
-      }
-    }
-
-    private void Puts(CacheableKey[] keys, Serializable[] values,
-      int offset, int numIters, int step)
-    {
-      if (keys != null && values != null && keys.Length == values.Length)
-      {
-        int numKeys = keys.Length;
-        if (numIters <= 0)
-        {
-          numIters = numKeys;
-        }
-        for (int i = offset; i < offset + numIters; i += step)
-        {
-          CacheHelper.CurrentRegion.Put(keys[i % numKeys], values[i % numKeys]);
-        }
-      }
-    }
-
-    private void Gets(CacheableKey[] keys,
-      int offset, int numIters, int step)
-    {
-      if (keys != null)
-      {
-        int numKeys = keys.Length;
-        if (numIters <= 0)
-        {
-          numIters = numKeys;
-        }
-        for (int i = offset; i < offset + numIters; i += step)
-        {
-          CacheHelper.CurrentRegion.Get(keys[i % numKeys]);
-        }
-      }
-    }
-
-    #endregion
-
-    #region Functions that are invoked by the tests
-
-    public enum RegionOp { Put, Get }
-    public enum KeysSelect { KeysA, KeysB, IntKeysA, IntKeysB }
-
-    public void InitKeysValues(int num)
-    {
-      InitStringObjects(num, "KeysA - ", ref keysA);
-      InitStringObjects(num, "KeysB - ", ref keysB);
-      InitStringObjects(num, "ValuesA - ", ref valuesA);
-      InitStringObjects(num, "ValuesB - ", ref valuesB);
-
-      InitIntObjects(num, 1, 2, ref intKeysA);
-      InitIntObjects(num, 0, 2, ref intKeysB);
-      InitIntObjects(num, 0, 2, ref intValuesA);
-      InitIntObjects(num, 1, 2, ref intValuesB);
-    }
-
-    public void RegionOpsAB(RegionOp op, KeysSelect sel,
-      int offset, int numIters, int step)
-    {
-      CacheableKey[] keys = null;
-      Serializable[] values = null;
-      switch (sel)
-      {
-        case KeysSelect.KeysA:
-          keys = (CacheableKey[])keysA;
-          values = (Serializable[])valuesA;
-          break;
-        case KeysSelect.KeysB:
-          keys = (CacheableKey[])keysB;
-          values = (Serializable[])valuesB;
-          break;
-        case KeysSelect.IntKeysA:
-          keys = (CacheableKey[])intKeysA;
-          values = (Serializable[])intValuesA;
-          break;
-        case KeysSelect.IntKeysB:
-          keys = (CacheableKey[])intKeysB;
-          values = (Serializable[])intValuesB;
-          break;
-      }
-      switch (op)
-      {
-        case RegionOp.Put:
-          Puts(keys, values, offset, numIters, step);
-          break;
-        case RegionOp.Get:
-          Gets(keys, offset, numIters, step);
-          break;
-      }
-    }
-
-    public void CheckNumKeys(int numExpected)
-    {
-      int numKeys = 0;
-      string message;
-      ISerializable[] keys = CacheHelper.CurrentRegion.GetKeys();
-      if (keys != null)
-      {
-        numKeys = keys.Length;
-      }
-      if (numExpected == 0)
-      {
-        message = "Region is not empty.";
-      }
-      else
-      {
-        message = "Region does not contain the expected number of entries.";
-      }
-      Assert.AreEqual(numExpected, numKeys, message);
-    }
-
-    #endregion
-
-    [TestFixtureSetUp]
-    public override void InitTests()
-    {
-      base.InitTests();
-
-      m_client1.Call(InitKeysValues, MaxKeys);
-      m_client2.Call(InitKeysValues, MaxKeys);
-      m_client3.Call(InitKeysValues, MaxKeys);
-      m_client4.Call(InitKeysValues, MaxKeys);
-    }
-
-    private void DoCommonDistribTests(string putTestName, int putIters,
-      string failTestName, int failIters, string proc2TestName)
-    {
-      StartTimer();
-      m_client1.Call(RegionOpsAB, RegionOp.Put, KeysSelect.KeysA, 0, putIters, 1);
-      LogTaskTiming(m_client1, putTestName, putIters);
-
-      StartTimer();
-      m_client1.Call(RegionOpsAB, RegionOp.Get, KeysSelect.KeysB, 0, failIters, 1);
-      LogTaskTiming(m_client1, failTestName, failIters);
-
-     
-      m_client2.Call(CheckNumKeys, 0);
-      StartTimer();
-      m_client2.Call(RegionOpsAB, RegionOp.Get, KeysSelect.KeysA, 0, MaxKeys, 1);
-      LogTaskTiming(m_client2, proc2TestName, MaxKeys);
-      m_client2.Call(CheckNumKeys, MaxKeys);
-    }
-
-    [Test]
-    public void NoPeers()
-    {
-      int numIters = 50 * MaxKeys;
-
-      m_client1.Call(CacheHelper.CreateScopeRegion, "LocalOnly", ScopeType.Local, true);
-
-      StartTimer();
-      m_client1.Call(RegionOpsAB, RegionOp.Put, KeysSelect.KeysA, 0, numIters, 1);
-      LogTaskTiming(m_client1, "LocalPuts", numIters);
-
-      StartTimer();
-      m_client1.Call(RegionOpsAB, RegionOp.Get, KeysSelect.KeysA, 0, numIters, 1);
-      LogTaskTiming(m_client1, "LocalGets", numIters);
-
-      StartTimer();
-      m_client1.Call(RegionOpsAB, RegionOp.Get, KeysSelect.KeysB, 0, numIters, 1);
-      LogTaskTiming(m_client1, "LocalFailGets", numIters);
-
-      m_client1.Call(CacheHelper.DestroyRegion, "LocalOnly", false, true);
-
-      m_client1.Call(CacheHelper.CreateScopeRegion, "DistNoPeers", ScopeType.DistributedNoAck, true);
-
-      StartTimer();
-      m_client1.Call(RegionOpsAB, RegionOp.Put, KeysSelect.KeysA, 0, numIters, 1);
-      LogTaskTiming(m_client1, "DistNoPeersPuts", numIters);
-
-      m_client1.Call(CacheHelper.DestroyRegion, "DistNoPeers", false, true);
-    }
-
-    [Test]
-    public void NoAck2Proc()
-    {
-      m_client1.Call(CacheHelper.CreateScopeRegion, "NoAck2Proc", ScopeType.DistributedNoAck, true);
-      m_client2.Call(CacheHelper.CreateScopeRegion, "NoAck2Proc", ScopeType.DistributedNoAck, true);
-
-      DoCommonDistribTests("NoAck2ProcPuts", 10 * MaxKeys,
-        "NoAck2ProcNetsearchFail", 2 * MaxKeys, "NoAck2ProcNetsearch");
-
-      m_client1.Call(CacheHelper.DestroyRegion, "NoAck2Proc", false, true);
-    }
-
-    [Test]
-    public void Ack2Proc()
-    {
-      m_client1.Call(CacheHelper.CreateScopeRegion, "Ack2Proc", ScopeType.DistributedAck, true);
-      m_client2.Call(CacheHelper.CreateScopeRegion, "Ack2Proc", ScopeType.DistributedAck, true);
-
-      DoCommonDistribTests("Ack2ProcPuts", 2 * MaxKeys,
-        "Ack2ProcNetsearchFail", MaxKeys, "Ack2ProcNetsearch");
-
-      m_client1.Call(CacheHelper.DestroyRegion, "Ack2Proc", false, true);
-    }
-
-    [Test]
-    public void NoAck3Proc()
-    {
-      m_client1.Call(CacheHelper.CreateScopeRegion, "NoAck3Proc", ScopeType.DistributedNoAck, true);
-      m_client2.Call(CacheHelper.CreateScopeRegion, "NoAck3Proc", ScopeType.DistributedNoAck, true);
-      m_client3.Call(CacheHelper.CreateScopeRegion, "NoAck3Proc", ScopeType.DistributedNoAck, true);
-
-      DoCommonDistribTests("NoAck3ProcPuts", 2 * MaxKeys,
-        "NoAck3ProcNetsearchFail", MaxKeys, "NoAck3ProcNetsearch");
-
-      m_client1.Call(CacheHelper.DestroyRegion, "NoAck3Proc", false, true);
-    }
-
-    [Test]
-    public void Ack3Proc()
-    {
-      m_client1.Call(CacheHelper.CreateScopeRegion, "Ack3Proc", ScopeType.DistributedAck, true);
-      m_client2.Call(CacheHelper.CreateScopeRegion, "Ack3Proc", ScopeType.DistributedAck, true);
-      m_client3.Call(CacheHelper.CreateScopeRegion, "Ack3Proc", ScopeType.DistributedAck, true);
-
-      DoCommonDistribTests("Ack3ProcPuts", MaxKeys,
-        "Ack3ProcNetsearchFail", MaxKeys, "Ack3ProcNetsearch");
-
-      m_client1.Call(CacheHelper.DestroyRegion, "Ack3Proc", false, true);
-    }
-
-    [Test]
-    public void NoAck4Proc()
-    {
-      m_client1.Call(CacheHelper.CreateScopeRegion, "NoAck4Proc", ScopeType.DistributedNoAck, true);
-      m_client2.Call(CacheHelper.CreateScopeRegion, "NoAck4Proc", ScopeType.DistributedNoAck, true);
-      m_client3.Call(CacheHelper.CreateScopeRegion, "NoAck4Proc", ScopeType.DistributedNoAck, true);
-      m_client4.Call(CacheHelper.CreateScopeRegion, "NoAck4Proc", ScopeType.DistributedNoAck, true);
-
-      DoCommonDistribTests("NoAck4ProcPuts", MaxKeys,
-        "NoAck4ProcNetsearchFail", MaxKeys, "NoAck4ProcNetsearch");
-
-      m_client1.Call(CacheHelper.DestroyRegion, "NoAck4Proc", false, true);
-    }
-
-    [Test]
-    public void Ack4Proc()
-    {
-      m_client1.Call(CacheHelper.CreateScopeRegion, "Ack4Proc", ScopeType.DistributedAck, true);
-      m_client2.Call(CacheHelper.CreateScopeRegion, "Ack4Proc", ScopeType.DistributedAck, true);
-      m_client3.Call(CacheHelper.CreateScopeRegion, "Ack4Proc", ScopeType.DistributedAck, true);
-      m_client4.Call(CacheHelper.CreateScopeRegion, "Ack4Proc", ScopeType.DistributedAck, true);
-
-      DoCommonDistribTests("Ack4ProcPuts", MaxKeys,
-        "Ack4ProcNetsearchFail", MaxKeys, "Ack4ProcNetsearch");
-
-      m_client1.Call(CacheHelper.DestroyRegion, "Ack4Proc", false, true);
-    }
-  }
-}
diff --git a/tests/cli/QueryHelper/QueryHelperN.cs b/clicache/integration-test/QueryHelperN.cs
similarity index 100%
rename from tests/cli/QueryHelper/QueryHelperN.cs
rename to clicache/integration-test/QueryHelperN.cs
diff --git a/clicache/integration-test/RegionEntryTests.cs b/clicache/integration-test/RegionEntryTests.cs
deleted file mode 100644
index 9c74bd0..0000000
--- a/clicache/integration-test/RegionEntryTests.cs
+++ /dev/null
@@ -1,105 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.UnitTests
-{
-  using NUnit.Framework;
-  using Apache.Geode.DUnitFramework;
-
-  [TestFixture]
-  [Category("unicast_only")]
-  public class RegionEntryTests : UnitTests
-  {
-    private const string hostName = "REGIONENTRYTEST";
-    private const string regionName = "TESTREGIONENTRY_ROOT_REGION";
-    private Region region;
-
-    protected override ClientBase[] GetClients()
-    {
-      return null;
-    }
-
-    [TestFixtureSetUp]
-    public override void InitTests()
-    {
-      base.InitTests();
-      CacheHelper.InitName(hostName, hostName);
-    }
-
-    [TestFixtureTearDown]
-    public override void EndTests()
-    {
-      try
-      {
-        CacheHelper.Close();
-      }
-      finally
-      {
-        base.EndTests();
-      }
-    }
-
-    public void TestEntries(Region region, int num)
-    {
-      string regionName = region.Name;
-      Util.Log("Creating {0} entries in Region {1}", num, regionName);
-
-      for (int i = 0; i < num; i++)
-      {
-        region.Create(regionName + ": " + i.ToString(),
-          regionName + ": value of " + i.ToString());
-      }
-      ICacheableKey[] cKeys = region.GetKeys();
-      ISerializable[] cValues = region.GetValues();
-      Assert.AreEqual(num, cKeys.Length, "Number of keys in region is incorrect.");
-      Assert.AreEqual(num, cValues.Length, "Number of values in region is incorrect.");
-
-      foreach (ICacheableKey key in cKeys)
-      {
-        region.LocalInvalidate(key);
-      }
-      cKeys = region.GetKeys();
-      cValues = region.GetValues();
-      Assert.AreEqual(num, cKeys.Length, "Number of keys in region is incorrect after invalidate.");
-      Assert.AreEqual(0, cValues.Length, "Number of values in region is incorrect after invalidate.");
-
-      foreach (ICacheableKey key in cKeys)
-      {
-        region.LocalDestroy(key);
-      }
-      cKeys = region.GetKeys();
-      cValues = region.GetValues();
-      Assert.AreEqual(0, cKeys.Length, "Number of keys in region is incorrect after destroy.");
-      Assert.AreEqual(0, cValues.Length, "Number of values in region is incorrect after destroy.");
-    }
-
-    [Test]
-    public void RegionEntryFunction()
-    {
-      CacheHelper.CreatePlainRegion(regionName);
-      region = CacheHelper.GetVerifyRegion(regionName);
-
-      TestEntries(region, 10);
-      TestEntries(region, 100);
-      TestEntries(region, 10000);
-
-      region.LocalDestroyRegion();
-    }
-  }
-}
diff --git a/clicache/integration-test/RegionFailingTests.cs b/clicache/integration-test/RegionFailingTests.cs
index da05188..5272822 100644
--- a/clicache/integration-test/RegionFailingTests.cs
+++ b/clicache/integration-test/RegionFailingTests.cs
@@ -26,6 +26,7 @@
   using DUnitFramework;
   using Client;
 
+  [Ignore("broken")]
   [TestFixture]
   [Category("group4")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientDeltaTestFailing.cs b/clicache/integration-test/ThinClientDeltaTestFailing.cs
index f940105..78c0f98 100644
--- a/clicache/integration-test/ThinClientDeltaTestFailing.cs
+++ b/clicache/integration-test/ThinClientDeltaTestFailing.cs
@@ -148,6 +148,7 @@
       #endregion
     }
 
+    [Ignore("broken")]
     [TestFixture]
     [Category("group1")]
     [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientDurableTestsN.cs b/clicache/integration-test/ThinClientDurableTestsN.cs
index 385a3ff..0a37257 100644
--- a/clicache/integration-test/ThinClientDurableTestsN.cs
+++ b/clicache/integration-test/ThinClientDurableTestsN.cs
@@ -27,6 +27,8 @@
 
 
   using AssertionException = Apache.Geode.Client.AssertionException;
+  
+  [Ignore("broken")]
   [TestFixture]
   [Category("group2")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientHARegionTestsN.cs b/clicache/integration-test/ThinClientHARegionTestsN.cs
index 87be756..0eced60 100644
--- a/clicache/integration-test/ThinClientHARegionTestsN.cs
+++ b/clicache/integration-test/ThinClientHARegionTestsN.cs
@@ -28,6 +28,7 @@
 
   using Region = Apache.Geode.Client.IRegion<Object, Object>;
 
+  [Ignore("broken")]
   [TestFixture]
   [Category("group4")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientPoolTestsN.cs b/clicache/integration-test/ThinClientPoolTestsN.cs
index 79ba314..84a6a0e 100644
--- a/clicache/integration-test/ThinClientPoolTestsN.cs
+++ b/clicache/integration-test/ThinClientPoolTestsN.cs
@@ -27,6 +27,7 @@
   using Apache.Geode.Client;
   using Region = Apache.Geode.Client.IRegion<Object, Object>;
 
+  [Ignore("flaky")]
   [TestFixture]
   [Category("group2")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientQueryTestsN.cs b/clicache/integration-test/ThinClientQueryTestsN.cs
index d4edc35..6004400 100644
--- a/clicache/integration-test/ThinClientQueryTestsN.cs
+++ b/clicache/integration-test/ThinClientQueryTestsN.cs
@@ -31,6 +31,7 @@
   using QueryCategory = Apache.Geode.Client.Tests.QueryCategory;
   using QueryStrings = Apache.Geode.Client.Tests.QueryStrings;
 
+  [Ignore("flaky")]
   [TestFixture]
   [Category("group1")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientSecurityAuthTestsMUN.cs b/clicache/integration-test/ThinClientSecurityAuthTestsMUN.cs
index 37df5fb..84bb93f 100644
--- a/clicache/integration-test/ThinClientSecurityAuthTestsMUN.cs
+++ b/clicache/integration-test/ThinClientSecurityAuthTestsMUN.cs
@@ -25,6 +25,8 @@
   using Apache.Geode.Client.Tests;
   using Apache.Geode.DUnitFramework;
   using Apache.Geode.Client;
+
+  [Ignore("broken")]
   [TestFixture]
   [Category("group4")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientSecurityAuthTestsN.cs b/clicache/integration-test/ThinClientSecurityAuthTestsN.cs
index 40062dc..de2bd7b 100644
--- a/clicache/integration-test/ThinClientSecurityAuthTestsN.cs
+++ b/clicache/integration-test/ThinClientSecurityAuthTestsN.cs
@@ -26,6 +26,7 @@
   using Apache.Geode.DUnitFramework;
   using Apache.Geode.Client;
 
+  [Ignore("broken")]
   [TestFixture]
   [Category("group1")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientSecurityAuthzTestsMUN.cs b/clicache/integration-test/ThinClientSecurityAuthzTestsMUN.cs
index 4ab7d21..1b1cb9f 100644
--- a/clicache/integration-test/ThinClientSecurityAuthzTestsMUN.cs
+++ b/clicache/integration-test/ThinClientSecurityAuthzTestsMUN.cs
@@ -71,6 +71,7 @@
     #endregion
   }
 
+  [Ignore("broken")]
   [TestFixture]
   [Category("group4")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/ThinClientSecurityAuthzTestsN.cs b/clicache/integration-test/ThinClientSecurityAuthzTestsN.cs
index 31bcd41..e608a1e 100644
--- a/clicache/integration-test/ThinClientSecurityAuthzTestsN.cs
+++ b/clicache/integration-test/ThinClientSecurityAuthzTestsN.cs
@@ -26,6 +26,7 @@
   using Apache.Geode.Client.Tests;
   using Apache.Geode.Client;
 
+  [Ignore("broken")]
   [TestFixture]
   [Category("group3")]
   [Category("unicast_only")]
diff --git a/clicache/integration-test/UnitTests.csproj.in b/clicache/integration-test/UnitTests.csproj.in
deleted file mode 100644
index c1c0152..0000000
--- a/clicache/integration-test/UnitTests.csproj.in
+++ /dev/null
@@ -1,679 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-	<CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-	<CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{CC6D226A-1DFF-31D1-89D1-D99420F6AF72}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Apache.Geode.Client.UnitTests</RootNamespace>
-    <AssemblyName>UnitTests</AssemblyName>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <Optimize>false</Optimize>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <NoWarn>618</NoWarn>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>618</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <Optimize>false</Optimize>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <NoWarn>618</NoWarn>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>618</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>618</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="nunit.framework">
-      <HintPath>${NUNIT}\bin\framework\nunit.framework.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Management" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\PortfolioPdx.cs">
-      <Link>PortfolioPdx.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\PositionPdx.cs">
-      <Link>PositionPdx.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\QueryHelper\QueryHelperN.cs">
-      <Link>QueryHelperN.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\Portfolio.cs">
-      <Link>Portfolio.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\Position.cs">
-      <Link>Position.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\SimpleCacheListener.cs">
-      <Link>SimpleCacheListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DataOutputTests.cs">
-      <Link>DataOutputTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DefaultCacheableN.cs">
-      <Link>DefaultCacheableN.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\TallyListener.cs">
-      <Link>TallyListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\TallyResolverN.cs">
-      <Link>TallyResolverN.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\TallyWriter.cs">
-      <Link>TallyWriter.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCallbackArgN.cs">
-      <Link>ThinClientCallbackArgN.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientDurableCqTestsN.cs">
-      <Link>ThinClientDurableCqTestsN.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientPdxTests1.cs">
-      <Link>ThinClientPdxTests1.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientPdxTests2.cs">
-      <Link>ThinClientPdxTests2.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientPdxTests3.cs">
-      <Link>ThinClientPdxTests3.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientNameTests.cs">
-      <Link>ThinClientNameTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientPdxLocalTests.cs">
-      <Link>ThinClientPdxLocalTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientPdxVersionTests.cs">
-      <Link>ThinClientPdxVersionTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientSecurityAuthSetAuthInitializeTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\RegionAttributesFactoryTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\AttributesMutatorTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\CacheHelperN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\CachelessTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DistOpsStepsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\PutGetTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\RegionWrapperN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\SecurityTestUtilN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\TallyListenerN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\TallyLoaderN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\TallyWriterN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionStepsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\RegionFailoverTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\RegionFailingTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\RegionRemoveTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\UnitTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestListTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestListWithPdxTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestList2Tests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestRegexInterestTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestRegexInterest2Tests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestRegexInterest3Tests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestResultPolicyInvTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestFailoverInterestTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestFailoverInterest2Tests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestFailoverRegexInterestTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionInterestNotifyTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientSecurityAuthTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientSecurityAuthTestsMUN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientSecurityAuthzTestBaseN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientSecurityAuthzTestsMUN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientSecurityAuthzTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientQueryTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRemoteQueryResultSetTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRemoteParamQueryResultSetTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRemoteQueryStructSetTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRemoteParamQueryStructSetTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRemoteQueryFailoverTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRemoteQueryExclusivenessTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientRegionQueryTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientAppDomainQueryTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientAppDomainFunctionExecutionTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\TestCacheXmlInitializationN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\BuiltinCacheableWrappersN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\CacheableWrapperN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DupListenerN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\RegionOperationN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientFunctionExecutionTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientHARegionTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientListenerWriterN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientPoolTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DurableListenerN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientDurableTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ExpirationTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\OverflowTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\SerializationTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientConflationTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCqIRTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCqPdxTest.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCqAttributesMutatorTests.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCqTest.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCqStatusTest.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCqStatusTestTwoServers.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientStringArrayTestsN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientCSTXN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientDeltaTest.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\ThinClientDeltaTestFailing.cs" />
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\DeltaTestImpl.cs">
-      <Link>DeltaTestImpl.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\TestObject1.cs">
-      <Link>TestObject1.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\tests\cli\NewTestObject\DeltaEx.cs">
-      <Link>DeltaEx.cs</Link>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="$(CMAKE_CURRENT_SOURCE_DIR)\geode.properties.mixed">
-      <Link>geode.properties.mixed</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="$(CMAKE_CURRENT_SOURCE_DIR)\geode.properties.nativeclient">
-      <Link>geode.properties.nativeclient</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </None>
-    <None Include="$(CMAKE_CURRENT_SOURCE_DIR)\system.properties">
-      <Link>system.properties</Link>
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-    </None>
-    <None Include="authz5_5.dtd" />
-    <None Include="cdb.pl" />
-    <None Include="runCSFunctions.sh" />
-    <None Include="runCSTests.sh" />
-  </ItemGroup>
-  <ItemGroup>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription_forDoc.xml">
-      <Link>cacheserver_notify_subscription_forDoc.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver1_partitioned.xml">
-      <Link>cacheserver1_partitioned.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver1_TradeKey.xml">
-      <Link>cacheserver1_TradeKey.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver2_partitioned.xml">
-      <Link>cacheserver2_partitioned.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver2_TradeKey.xml">
-      <Link>cacheserver2_TradeKey.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver3_TradeKey.xml">
-      <Link>cacheserver3_TradeKey.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserverDurableCqs.xml">
-      <Link>cacheserverDurableCqs.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_pdxinstance_hashcode.xml">
-      <Link>cacheserver_pdxinstance_hashcode.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_servergroup.xml">
-      <Link>cacheserver_servergroup.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_servergroup2.xml">
-      <Link>cacheserver_servergroup2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\client_generics_plugins.xml">
-      <Link>client_generics_plugins.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\client_pdx.xml">
-      <Link>client_pdx.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\Settings.xml">
-      <Link>Settings.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\Timeouts.xml">
-      <Link>Timeouts.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\valid_overflowAttr.xml">
-      <Link>valid_overflowAttr.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver.xml">
-      <Link>cacheserver.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserverPdxSerializer.xml">
-      <Link>cacheserverPdxSerializer.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheServer_pdxreadserialized.xml">
-      <Link>cacheServer_pdxreadserialized.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserverPdx2.xml">
-      <Link>cacheserverPdx2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserverForPdx.xml">
-      <Link>cacheserverForPdx.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserverMDS1.xml">
-      <Link>cacheserverMDS1.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserverMDS2.xml">
-      <Link>cacheserverMDS2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserverPdx.xml">
-      <Link>cacheserverPdx.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver1_expiry.xml">
-      <Link>cacheserver1_expiry.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver1_fpr.xml">
-      <Link>cacheserver1_fpr.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver1_pool.xml">
-      <Link>cacheserver1_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver1_pr.xml">
-      <Link>cacheserver1_pr.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver2.xml">
-      <Link>cacheserver2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver2_fpr.xml">
-      <Link>cacheserver2_fpr.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver2_pool.xml">
-      <Link>cacheserver2_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver2_pr.xml">
-      <Link>cacheserver2_pr.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver3.xml">
-      <Link>cacheserver3.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver3_fpr.xml">
-      <Link>cacheserver3_fpr.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver3_pool.xml">
-      <Link>cacheserver3_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver3_pr.xml">
-      <Link>cacheserver3_pr.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_conflation.xml">
-      <Link>cacheserver_conflation.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_hashcode.xml">
-      <Link>cacheserver_hashcode.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_interest_notify.xml">
-      <Link>cacheserver_interest_notify.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription.xml">
-      <Link>cacheserver_notify_subscription.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription2.xml">
-      <Link>cacheserver_notify_subscription2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription3.xml">
-      <Link>cacheserver_notify_subscription3.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription4.xml">
-      <Link>cacheserver_notify_subscription4.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription5.xml">
-      <Link>cacheserver_notify_subscription5.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription5N.xml">
-      <Link>cacheserver_notify_subscription5N.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_notify_subscription6.xml">
-      <Link>cacheserver_notify_subscription6.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_pool_client.xml">
-      <Link>cacheserver_pool_client.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_remoteoql.xml">
-      <Link>cacheserver_remoteoql.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_remoteoql2.xml">
-      <Link>cacheserver_remoteoql2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_remoteoqlN.xml">
-      <Link>cacheserver_remoteoqlN.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_remoteoql2N.xml">
-      <Link>cacheserver_remoteoql2N.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_with_delta.xml">
-      <Link>cacheserver_with_delta.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_with_deltaAD.xml">
-      <Link>cacheserver_with_deltaAD.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cacheserver_with_delta_test_impl.xml">
-      <Link>cacheserver_with_delta_test_impl.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\CacheServPoolRedun1.xml">
-      <Link>CacheServPoolRedun1.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\CacheServPoolRedun2.xml">
-      <Link>CacheServPoolRedun2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\CacheServPoolRedun3.xml">
-      <Link>CacheServPoolRedun3.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cache_redundancy.xml">
-      <Link>cache_redundancy.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\client_pool.xml">
-      <Link>client_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_cache1.xml">
-      <Link>invalid_cache1.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_cache2.xml">
-      <Link>invalid_cache2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_cache3.xml">
-      <Link>invalid_cache3.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_cache_pool.xml">
-      <Link>invalid_cache_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_cache_pool2.xml">
-      <Link>invalid_cache_pool2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_cache_pool3.xml">
-      <Link>invalid_cache_pool3.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_cache_pool4.xml">
-      <Link>invalid_cache_pool4.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_overflowAttr1.xml">
-      <Link>invalid_overflowAttr1.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_overflowAttr2.xml">
-      <Link>invalid_overflowAttr2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\invalid_overflowAttr3.xml">
-      <Link>invalid_overflowAttr3.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\regionquery_diffconfig.xml">
-      <Link>regionquery_diffconfig.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\regionquery_diffconfig2.xml">
-      <Link>regionquery_diffconfig2.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\regionquery_diffconfigN.xml">
-      <Link>regionquery_diffconfigN.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\regionquery_diffconfig2N.xml">
-      <Link>regionquery_diffconfig2N.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\remotequery.xml">
-      <Link>remotequery.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\remotequeryN.xml">
-      <Link>remotequeryN.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\cqqueryfailover.xml">
-      <Link>cqqueryfailover.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\serverDurableClient.xml">
-      <Link>serverDurableClient.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\valid_cache.xml">
-      <Link>valid_cache.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\valid_cache_pool.xml">
-      <Link>valid_cache_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\multi_get_function_server.xml">
-      <Link>multi_get_function_server.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\func_cacheserver1_pool.xml">
-      <Link>func_cacheserver1_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\func_cacheserver2_pool.xml">
-      <Link>func_cacheserver2_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\func_cacheserver3_pool.xml">
-      <Link>func_cacheserver3_pool.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\client_server_persistent_transactions.xml">
-      <Link>client_server_persistent_transactions.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\client_server_transactions.xml">
-      <Link>client_server_transactions.xml</Link>
-      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
-    </Content>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\CMakeLists.txt"/>
-    <Content Include="$(CMAKE_CURRENT_SOURCE_DIR)\UnitTests.csproj.in"/>
-    <Content Include="authz-dummy.xml" />
-    <Content Include="authz-ldap.xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\plugins\SQLiteCLI\Apache.Geode.Plugins.SQLite.csproj">
-      <Project>{FF9597E3-A4DD-4FDE-871D-B0C66088762F}</Project>
-      <Name>SQLiteCLI</Name>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\clicache\src\Apache.Geode.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\tests\cli\DUnitFramework\DUnitFramework.csproj">
-      <Project>{796727E8-3A6A-46BE-A2DB-584A4774CD51}</Project>
-      <Name>DUnitFramework</Name>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\tests\cli\FwkClient\FwkClient.csproj">
-      <Project>{9EFAA401-B5D1-4592-A2FF-0972C776FF6A}</Project>
-      <Name>FwkClient</Name>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\tests\cli\PdxClassLibrary\PdxClassLibrary.csproj">
-      <Project>{10613802-A371-4C27-8F66-CE79BFCAC3F2}</Project>
-      <Name>PdxClassLibrary</Name>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\tests\cli\PdxVersion1Lib\PdxVersion1Lib.csproj">
-      <Project>{97F9965D-6B3D-44F6-92B3-5880A3C7178E}</Project>
-      <Name>PdxVersion1Lib</Name>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\tests\cli\PdxVersion2Lib\PdxVersion2Lib.csproj">
-      <Project>{5055633B-6D1C-488D-B934-1AC482C915F7}</Project>
-      <Name>PdxVersion2Lib</Name>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\tests\cli\QueryHelper\QueryWrapper.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-      <Name>QueryWrapper</Name>
-    </ProjectReference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\tests\cli\SecurityUtil\SecurityUtil.csproj">
-      <Project>{29CFC13C-1D6C-4FE8-B56E-A5E7BA7F849F}</Project>
-      <Name>SecurityUtil</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-  <PropertyGroup>
-    <PostBuildEvent>
-    </PostBuildEvent>
-  </PropertyGroup>
-</Project>
diff --git a/clicache/integration-test/packages.config b/clicache/integration-test/packages.config
new file mode 100644
index 0000000..88fa04b
--- /dev/null
+++ b/clicache/integration-test/packages.config
@@ -0,0 +1,22 @@
+<?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.
+-->
+<packages>
+  <package id="NUnit" version="2.6.4" targetFramework="net35" />
+  <package id="NUnit.Runners" version="2.6.4" targetFramework="net35" />
+  <package id="NUnitTestAdapter" version="2.3.0" targetFramework="net35" />
+</packages>
diff --git a/clicache/integration-test/test.bat.in b/clicache/integration-test/test.bat.in
deleted file mode 100644
index 31fbe33..0000000
--- a/clicache/integration-test/test.bat.in
+++ /dev/null
@@ -1,49 +0,0 @@
-@echo off
-
-rem Licensed to the Apache Software Foundation (ASF) under one or more
-rem contributor license agreements.  See the NOTICE file distributed with
-rem this work for additional information regarding copyright ownership.
-rem The ASF licenses this file to You under the Apache License, Version 2.0
-rem (the "License"); you may not use this file except in compliance with
-rem the License.  You may obtain a copy of the License at
-rem 
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem 
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-setlocal
-
-set PATH=$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:Apache.Geode>>;%PATH%
-set PATH=$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:framework>>;%PATH%
-set PATH=$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:testobject>>;%PATH%
-set PATH=$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:SqLiteImpl>>;%PATH%
-set PATH=$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:securityImpl>>;%PATH%
-set PATH=$<JOIN:$<SHELL_PATH:${PATH}>,;>;%PATH%
-
-set PATH=c:\Program Files (x86)\Nunit 2.6.4\bin;%PATH%
-
-set TEST_DIR="$<SHELL_PATH:${TEST_DIR}>"
-set GEODE_NATIVE_HOME="%TEST_DIR%"
-
-set TESTSRC=$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}>
-set GF_JAVA=$<SHELL_PATH:${Java_JAVA_EXECUTABLE}>
-set GFE_LOGLEVEL=config
-set GFE_SECLOGLEVEL=config
-set GFE_DIR=$<SHELL_PATH:${Geode_PATH}>
-set GF_CLASSPATH=%GF_CLASSPATH%;$<SHELL_PATH:${CMAKE_BINARY_DIR}>\tests\javaobject\javaobject.jar
-
-rmdir /q /s "%TEST_DIR%" 2>nul
-mkdir "%TEST_DIR%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-pushd "%TEST_DIR%"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-${NUNIT_CONSOLE} /timeout 1000000 /labels /run:${NAMESPACE}.${TESTCLASS} ..\..\$<CONFIG>\UnitTests.dll
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-popd
-exit /b
diff --git a/clicache/integration-test/test.runsettings.in b/clicache/integration-test/test.runsettings.in
new file mode 100644
index 0000000..57e2004
--- /dev/null
+++ b/clicache/integration-test/test.runsettings.in
@@ -0,0 +1,30 @@
+<?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.
+-->
+<RunSettings>
+  <RunConfiguration>
+    <EnvironmentVariables>
+      <TESTSRC>$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}></TESTSRC>
+      <GFE_LOGLEVEL>config</GFE_LOGLEVEL>
+      <GFE_SECLOGLEVEL>config</GFE_SECLOGLEVEL>
+      <GF_JAVA>$<SHELL_PATH:${Java_JAVA_EXECUTABLE}></GF_JAVA>
+      <GFE_DIR>$<SHELL_PATH:${Geode_PATH}></GFE_DIR>
+      <GF_CLASSPATH>$<SHELL_PATH:${CMAKE_BINARY_DIR}/tests/javaobject/javaobject.jar></GF_CLASSPATH>
+      <PATH>$<SHELL_PATH:${CMAKE_BINARY_DIR}/packages/NUnit.Runners.2.6.4/tools></PATH>
+    </EnvironmentVariables>
+  </RunConfiguration>
+</RunSettings>
diff --git a/clicache/integration-test2/CMakeLists.txt b/clicache/integration-test2/CMakeLists.txt
index d387de9..a5b0de3 100644
--- a/clicache/integration-test2/CMakeLists.txt
+++ b/clicache/integration-test2/CMakeLists.txt
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 cmake_minimum_required( VERSION 3.9 )
-project( Apache.Geode.IntegrationTests2 CSharp )
+project(Apache.Geode.IntegrationTests2 CSharp)
 
 set(CMAKE_CSharp_FLAGS "/langversion:5")
 
@@ -23,7 +23,7 @@
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages.config ${CMAKE_CURRENT_BINARY_DIR}/packages.config COPYONLY)
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cs.in ${CMAKE_CURRENT_BINARY_DIR}/Config.cs)
 
-add_library( ${PROJECT_NAME} SHARED
+add_library( Apache.Geode.IntegrationTests2 SHARED
   Framework.cs
   Cluster.cs
   ClusterTest.cs
@@ -47,6 +47,7 @@
   cache.xml
   geode.properties
   xunit.runner.json
+  xUnitTestAddTests.ps1
   packages.config
   AutoSerializationTests.cs
   SerializationTests.cs
@@ -58,39 +59,65 @@
   xunit.runner.json
   geode.properties
   PROPERTIES
-    VS_COPY_TO_OUT_DIR Always
+    VS_COPY_TO_OUT_DIR PreserveNewest
     VS_TOOL_OVERRIDE None
 )
 
-target_link_libraries(${PROJECT_NAME}
+target_link_libraries(Apache.Geode.IntegrationTests2
   PUBLIC
     Apache.Geode
     PdxClassLibrary
 )
 
-set_target_properties( ${PROJECT_NAME} PROPERTIES
-  COMMON_LANGUAGE_RUNTIME ""
-  VS_GLOBAL_ROOTNAMESPACE ${PROJECT_NAME}
+set_target_properties(Apache.Geode.IntegrationTests2 PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode.IntegrationTests2
   VS_GLOBAL_TreatWarningsAsErrors True
   VS_GLOBAL_IsTestProject True
   VS_GLOBAL_TestProjectType UnitTest
   VS_GLOBAL_PROJECT_TYPES "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
   VS_DOTNET_REFERENCES "System;System.Xml;System.Web;System.Configuration"
-  VS_DOTNET_REFERENCE_Microsoft.VisualStudio.TestPlatform.TestFramework "${CMAKE_BINARY_DIR}/clicache/packages/Microsoft.VisualStudio.TestPlatform.14.0.0.1/lib/net20/Microsoft.VisualStudio.TestPlatform.TestFramework.dll"
-  VS_DOTNET_REFERENCE_Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions "${CMAKE_BINARY_DIR}/clicache/packages/Microsoft.VisualStudio.TestPlatform.14.0.0.1/lib/net20/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll"
-  VS_DOTNET_REFERENCE_xunit.core "${CMAKE_BINARY_DIR}/clicache/packages/xunit.extensibility.core.2.4.0/lib/netstandard1.1/xunit.core.dll"
-  VS_DOTNET_REFERENCE_xunit.assert "${CMAKE_BINARY_DIR}/clicache/packages/xunit.assert.2.4.0/lib/netstandard1.1/xunit.assert.dll"
-  VS_DOTNET_REFERENCE_xunit.abstractions "${CMAKE_BINARY_DIR}/clicache/packages/xunit.abstractions.2.0.2/lib/net35/xunit.abstractions.dll"
-  VS_DOTNET_REFERENCE_xunit.execution.desktop "${CMAKE_BINARY_DIR}/clicache/packages/xunit.extensibility.execution.2.4.0/lib/net452/xunit.execution.desktop.dll"
-  VS_DOTNET_REFERENCE_xunit.runner.visualstudio.testadapter "${CMAKE_BINARY_DIR}/clicache/packages/xunit.runner.visualstudio.2.4.0/build/_common/xunit.runner.visualstudio.testadapter.dll"
+  VS_DOTNET_REFERENCE_xunit.core "${CMAKE_BINARY_DIR}/packages/xunit.extensibility.core.2.4.0/lib/netstandard1.1/xunit.core.dll"
+  VS_DOTNET_REFERENCE_xunit.assert "${CMAKE_BINARY_DIR}/packages/xunit.assert.2.4.0/lib/netstandard1.1/xunit.assert.dll"
+  VS_DOTNET_REFERENCE_xunit.abstractions "${CMAKE_BINARY_DIR}/packages/xunit.abstractions.2.0.2/lib/net35/xunit.abstractions.dll"
+  VS_DOTNET_REFERENCE_xunit.execution.desktop "${CMAKE_BINARY_DIR}/packages/xunit.extensibility.execution.2.4.0/lib/net452/xunit.execution.desktop.dll"
+  VS_DOTNET_REFERENCE_xunit.runner.visualstudio.testadapter "${CMAKE_BINARY_DIR}/packages/xunit.runner.visualstudio.2.4.0/build/_common/xunit.runner.visualstudio.testadapter.dll"
   FOLDER cli/test/integration
 )
 
 if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
-  set_target_properties( ${PROJECT_NAME} PROPERTIES
+  set_target_properties( Apache.Geode.IntegrationTests2 PROPERTIES
     VS_GLOBAL_SignAssembly "true"
     VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
   )
 endif()
 
-add_dependencies(${PROJECT_NAME} nuget-restore)
+add_dependencies(Apache.Geode.IntegrationTests2 nuget-restore)
+
+enable_testing()
+
+set(ctest_file_base "${CMAKE_CURRENT_BINARY_DIR}/xUnit")
+set(ctest_include_file "${ctest_file_base}_include.cmake")
+set(ctest_tests_file "${ctest_file_base}_tests.cmake")
+
+add_custom_command(
+  TARGET Apache.Geode.IntegrationTests2 POST_BUILD
+  BYPRODUCTS "${ctest_tests_file}"
+  COMMAND pwsh -File 
+          "$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}/xUnitTestAddTests.ps1>"
+          -AssemblyPath "$<SHELL_PATH:$<TARGET_FILE:Apache.Geode.IntegrationTests2>>"
+          -XUnitConsolePath "$<SHELL_PATH:${CMAKE_BINARY_DIR}/packages/xunit.runner.console.2.4.0/tools/net452/xunit.console.exe>"
+          -CTestFile "$<SHELL_PATH:${ctest_tests_file}>"
+  WORKING_DIRECTORY "$<TARGET_FILE_DIR:Apache.Geode.IntegrationTests2>"
+)
+
+file(WRITE "${ctest_include_file}"
+  "if(EXISTS \"${ctest_tests_file}\")\n"
+  "  include(\"${ctest_tests_file}\")\n"
+  "else()\n"
+  "  add_test(${TARGET}_NOT_BUILT ${TARGET}_NOT_BUILT)\n"
+  "endif()\n"
+)
+
+set_property(DIRECTORY
+  APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
+)
diff --git a/clicache/integration-test2/packages.config b/clicache/integration-test2/packages.config
index e7d725b..fb25d57 100644
--- a/clicache/integration-test2/packages.config
+++ b/clicache/integration-test2/packages.config
@@ -16,7 +16,6 @@
   limitations under the License.
 -->
 <packages>
-  <package id="Microsoft.VisualStudio.TestPlatform" version="14.0.0.1" targetFramework="net452" />
   <package id="xunit" version="2.4.0" targetFramework="net452" />
   <package id="xunit.abstractions" version="2.0.2" targetFramework="net35" />
   <package id="xunit.analyzers" version="0.10.0" targetFramework="net452" />
diff --git a/clicache/integration-test2/xUnitTestAddTests.ps1 b/clicache/integration-test2/xUnitTestAddTests.ps1
new file mode 100644
index 0000000..f948110
--- /dev/null
+++ b/clicache/integration-test2/xUnitTestAddTests.ps1
@@ -0,0 +1,54 @@
+# 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.
+
+Param
+(
+    [Parameter(Mandatory)]
+    [string]$AssemblyPath,
+    [Parameter(Mandatory)]
+    [string]$XUnitConsolePath,
+    [Parameter(Mandatory)]
+    [string]$CTestFile
+)
+
+#$ErrorActionPreference = "Stop
+
+Remove-Item -Path $CTestFile -Force -ErrorAction Ignore 
+
+$xunit = [reflection.assembly]::LoadFrom("xunit.core.dll")
+
+$assembly = [reflection.assembly]::LoadFrom($AssemblyPath)
+
+foreach ($type in $assembly.GetTypes())
+{
+    foreach ($method in $type.GetMethods())
+    {
+        foreach ($customAttribute in $method.CustomAttributes)
+        {
+            if ($customAttribute.AttributeType.Equals([Xunit.FactAttribute]))
+            {
+                $testName = "$($method.ReflectedType.NameSpace).$($method.ReflectedType.Name).$($method.Name)"
+                Add-Content -Path $CTestFile -Value "add_test( $testName [==[$XUnitConsolePath]==] [==[$AssemblyPath]==] -nologo -method $testName )"
+                foreach ($namedArgument in $customAttribute.NamedArguments)
+                {
+                    if ($namedArgument.MemberName -eq "Skip")
+                    {
+                        Add-Content -Path $CTestFile -Value "set_tests_properties( $testName PROPERTIES DISABLED True )"
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/clicache/src/CMakeLists.txt b/clicache/src/CMakeLists.txt
index eddf595..7190903 100644
--- a/clicache/src/CMakeLists.txt
+++ b/clicache/src/CMakeLists.txt
@@ -368,8 +368,6 @@
 
 add_dependencies(client-libraries Apache.Geode)
 
-add_subdirectory(templates)
-
 
 # For Visual Studio organization
 source_group("Configure In Files" FILES ${CONFIGURE_IN_FILES})
diff --git a/clicache/src/impl/AppDomainContext.hpp b/clicache/src/impl/AppDomainContext.hpp
index 0fd6581..d1fc1aa 100644
--- a/clicache/src/impl/AppDomainContext.hpp
+++ b/clicache/src/impl/AppDomainContext.hpp
@@ -20,8 +20,11 @@
 
 #include <functional>
 #include <vcclr.h>
+#include <msclr/marshal_cppstd.h>
+#include <debugapi.h>
 #include "../begin_native.hpp"
 #include <AppDomainContext.hpp>
+#include <geode/ExceptionTypes.hpp>
 #include "../end_native.hpp"
 
 namespace Apache
@@ -61,7 +64,11 @@
   }
   
   void run(runnable func) {
-    functionPointer(func);
+    try {
+      functionPointer(func);
+    } catch (AppDomainUnloadedException^) {
+      // if AppDomain has unloaded then we are shutting down so we can ignore.
+    }
   }
 
 private:
diff --git a/clicache/src/impl/AssemblyInfo.cpp.in b/clicache/src/impl/AssemblyInfo.cpp.in
index 4d80e02..f5c82b2 100644
--- a/clicache/src/impl/AssemblyInfo.cpp.in
+++ b/clicache/src/impl/AssemblyInfo.cpp.in
@@ -42,5 +42,5 @@
 
 [assembly:SecurityPermission(SecurityAction::RequestMinimum, UnmanagedCode = true)];
 
-[assembly:InternalsVisibleToAttribute("UnitTests@STRONG_NAME_PUBLIC_KEY_ATTRIBUTE@")];
+[assembly:InternalsVisibleToAttribute("Apache.Geode.Client.UnitTests@STRONG_NAME_PUBLIC_KEY_ATTRIBUTE@")];
 [assembly:InternalsVisibleToAttribute("cli-unit-tests@STRONG_NAME_PUBLIC_KEY_ATTRIBUTE@")];
diff --git a/clicache/src/templates/CMakeLists.txt b/clicache/src/templates/CMakeLists.txt
deleted file mode 100644
index 6c5f4e7..0000000
--- a/clicache/src/templates/CMakeLists.txt
+++ /dev/null
@@ -1,26 +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.
-cmake_minimum_required(VERSION 3.4)
-project(nativeclient.clicache.templates)
-
-foreach(var CMAKE_CURRENT_SOURCE_DIR CMAKE_SOURCE_DIR CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR)
-  file(TO_NATIVE_PATH ${${var}} ${var}_NATIVE)
-endforeach()
-
-configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Templates.csproj.in ${CMAKE_BINARY_DIR}/clicache/templates/Templates.csproj)  
-
-include_external_msproject(
-      Templates   ${CMAKE_BINARY_DIR}/clicache/templates/Templates.csproj
-      TYPE FAE04EC0-301F-11D3-BF4B-00C04F79EFBC)
diff --git a/clicache/src/templates/Templates.csproj.in b/clicache/src/templates/Templates.csproj.in
deleted file mode 100644
index 65b5f8a..0000000
--- a/clicache/src/templates/Templates.csproj.in
+++ /dev/null
@@ -1,137 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-    <CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-    <CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{1B99F0C4-B241-45C7-BFAF-2009D0664901}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Apache.Geode.Templates.Cache.Security</RootNamespace>
-    <AssemblyName>Apache.Geode.Templates.Cache.Security</AssemblyName>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <ItemGroup>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\clicache\src\Apache.Geode.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-    <Reference Include="System" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\templates\security\csharp\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_SOURCE_DIR)\templates\security\csharp\UserPasswordAuthInit.cs">
-      <Link>UserPasswordAuthInit.cs</Link>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="$(CMAKE_SOURCE_DIR)\clicache\keys\gemfire.snk" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/clicache/test/CMakeLists.txt b/clicache/test/CMakeLists.txt
index f53a087..a47f10d 100644
--- a/clicache/test/CMakeLists.txt
+++ b/clicache/test/CMakeLists.txt
@@ -16,6 +16,10 @@
 cmake_minimum_required(VERSION 3.10)
 project(Apache.Geode.Test CXX)
 
+set(vstest_dir ${CMAKE_BINARY_DIR}/packages/Microsoft.TestPlatform.16.8.3/tools/net451/Common7/IDE/Extensions/TestPlatform)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages.config ${CMAKE_CURRENT_BINARY_DIR}/packages.config COPYONLY)
+
 if(NOT "${STRONG_NAME_PUBLIC_KEY}" STREQUAL "")
   set(STRONG_NAME_PUBLIC_KEY_ATTRIBUTE ", PublicKey=${STRONG_NAME_PUBLIC_KEY}")
 endif()
@@ -30,6 +34,7 @@
   native_unique_ptrTests.cpp
   TimeUtilsTests.cpp
   ${CONFIGURE_OUT_FILES}
+  packages.config
 )
 
 set_target_properties(Apache.Geode.Test PROPERTIES
@@ -40,7 +45,8 @@
   VS_GLOBAL_TestProjectType UnitTest
   VS_GLOBAL_PROJECT_TYPES "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}"
   VS_GLOBAL_ROOTNAMESPACE Apache.Geode.Test
-  VS_DOTNET_REFERENCES "System;System.Xml;Microsoft.VisualStudio.QualityTools.UnitTestFramework"
+  VS_DOTNET_REFERENCES "System;System.Xml"
+  VS_DOTNET_REFERENCE_Microsoft.VisualStudio.QualityTools.UnitTestFramework "${vstest_dir}/Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll"
   FOLDER cli/test/unit
 )
 
@@ -62,6 +68,7 @@
 
 # Makes project only reference, no .lib.
 add_dependencies(Apache.Geode.Test Apache.Geode)
+add_dependencies(Apache.Geode.Test nuget-restore)
 
 string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
 set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${SHARED_LINKER_FLAGS_STRONG_KEY}")
@@ -69,3 +76,12 @@
 # For Visual Studio organization
 source_group("Configure In Files" FILES ${CONFIGURE_IN_FILES})
 source_group("Configure Out Files" FILES ${CONFIGURE_OUT_FILES})
+
+enable_testing()
+
+add_test(NAME Apache.Geode.Test
+  COMMAND ${vstest_dir}/vstest.console.exe
+          $<SHELL_PATH:$<TARGET_FILE:Apache.Geode.Test>>
+          --nologo --parallel
+  WORKING_DIRECTORY "$<TARGET_FILE_DIR:Apache.Geode.Test>"
+)
diff --git a/clicache/test/packages.config b/clicache/test/packages.config
new file mode 100644
index 0000000..96f4dcc
--- /dev/null
+++ b/clicache/test/packages.config
@@ -0,0 +1,20 @@
+<?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.
+-->
+<packages>
+  <package id="Microsoft.TestPlatform" version="16.8.3" targetFramework="net452" />
+</packages>
diff --git a/clicache/test2/CMakeLists.txt b/clicache/test2/CMakeLists.txt
index 567fa59..3dd7e8c 100644
--- a/clicache/test2/CMakeLists.txt
+++ b/clicache/test2/CMakeLists.txt
@@ -17,6 +17,7 @@
 project( Apache.Geode.Tests2 CSharp )
 
 set(CMAKE_CSharp_FLAGS "/langversion:5")
+set(vstest_dir ${CMAKE_BINARY_DIR}/packages/Microsoft.TestPlatform.16.8.3/tools/net451/Common7/IDE/Extensions/TestPlatform)
 
 configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages.config ${CMAKE_CURRENT_BINARY_DIR}/packages.config COPYONLY)
 
@@ -38,20 +39,17 @@
 )
 
 set_target_properties(Apache.Geode.Tests2 PROPERTIES
-  COMMON_LANGUAGE_RUNTIME "" 
   VS_GLOBAL_ROOTNAMESPACE ${PROJECT_NAME}
   VS_GLOBAL_TreatWarningsAsErrors True
   VS_GLOBAL_IsTestProject True
   VS_GLOBAL_TestProjectType UnitTest
   VS_GLOBAL_PROJECT_TYPES "{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
   VS_DOTNET_REFERENCES "System;System.Xml;System.Web;System.Configuration"
-  VS_DOTNET_REFERENCE_Microsoft.VisualStudio.TestPlatform.TestFramework "${CMAKE_BINARY_DIR}/clicache/packages/Microsoft.VisualStudio.TestPlatform.14.0.0.1/lib/net20/Microsoft.VisualStudio.TestPlatform.TestFramework.dll"
-  VS_DOTNET_REFERENCE_Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions "${CMAKE_BINARY_DIR}/clicache/packages/Microsoft.VisualStudio.TestPlatform.14.0.0.1/lib/net20/Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll"
-  VS_DOTNET_REFERENCE_xunit.core "${CMAKE_BINARY_DIR}/clicache/packages/xunit.extensibility.core.2.4.0/lib/netstandard1.1/xunit.core.dll"
-  VS_DOTNET_REFERENCE_xunit.assert "${CMAKE_BINARY_DIR}/clicache/packages/xunit.assert.2.4.0/lib/netstandard1.1/xunit.assert.dll"
-  VS_DOTNET_REFERENCE_xunit.abstractions "${CMAKE_BINARY_DIR}/clicache/packages/xunit.abstractions.2.0.2/lib/net35/xunit.abstractions.dll"
-  VS_DOTNET_REFERENCE_xunit.execution.desktop "${CMAKE_BINARY_DIR}/clicache/packages/xunit.extensibility.execution.2.4.0/lib/net452/xunit.execution.desktop.dll"
-  VS_DOTNET_REFERENCE_xunit.runner.visualstudio.testadapter "${CMAKE_BINARY_DIR}/clicache/packages/xunit.runner.visualstudio.2.4.0/build/_common/xunit.runner.visualstudio.testadapter.dll"
+  VS_DOTNET_REFERENCE_xunit.core "${CMAKE_BINARY_DIR}/packages/xunit.extensibility.core.2.4.0/lib/netstandard1.1/xunit.core.dll"
+  VS_DOTNET_REFERENCE_xunit.assert "${CMAKE_BINARY_DIR}/packages/xunit.assert.2.4.0/lib/netstandard1.1/xunit.assert.dll"
+  VS_DOTNET_REFERENCE_xunit.abstractions "${CMAKE_BINARY_DIR}/packages/xunit.abstractions.2.0.2/lib/net35/xunit.abstractions.dll"
+  VS_DOTNET_REFERENCE_xunit.execution.desktop "${CMAKE_BINARY_DIR}/packages/xunit.extensibility.execution.2.4.0/lib/net452/xunit.execution.desktop.dll"
+  VS_DOTNET_REFERENCE_xunit.runner.visualstudio.testadapter "${CMAKE_BINARY_DIR}/packages/xunit.runner.visualstudio.2.4.0/build/_common/xunit.runner.visualstudio.testadapter.dll"
   FOLDER cli/test/unit
 )
 
@@ -63,3 +61,12 @@
 endif()
 
 add_dependencies(Apache.Geode.Tests2 nuget-restore)
+
+enable_testing()
+
+add_test(NAME Apache.Geode.Tests2
+  COMMAND ${vstest_dir}/vstest.console.exe
+          $<SHELL_PATH:$<TARGET_FILE:Apache.Geode.Tests2>>
+          --nologo --platform:x64 --parallel
+  WORKING_DIRECTORY "$<TARGET_FILE_DIR:Apache.Geode.Tests2>"
+)
diff --git a/clicache/test2/ObjectsTests.cs b/clicache/test2/ObjectsTests.cs
index 6859491..714444b 100644
--- a/clicache/test2/ObjectsTests.cs
+++ b/clicache/test2/ObjectsTests.cs
@@ -1,4 +1,4 @@
-﻿/*
+/*
  * 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.
diff --git a/clicache/test2/packages.config b/clicache/test2/packages.config
index 02bf7df..ab73661 100644
--- a/clicache/test2/packages.config
+++ b/clicache/test2/packages.config
@@ -16,7 +16,7 @@
 limitations under the License.
 -->
 <packages>
-  <package id="Microsoft.VisualStudio.TestPlatform" version="14.0.0.1" targetFramework="net452" />
+  <package id="Microsoft.TestPlatform" version="16.8.3" targetFramework="net452" />
   <package id="xunit" version="2.4.0" targetFramework="net452" />
   <package id="xunit.abstractions" version="2.0.2" targetFramework="net35" />
   <package id="xunit.analyzers" version="0.10.0" targetFramework="net452" />
diff --git a/cppcache/integration-test/CMakeLists.txt b/cppcache/integration-test/CMakeLists.txt
index 8542865..a2ceb77 100644
--- a/cppcache/integration-test/CMakeLists.txt
+++ b/cppcache/integration-test/CMakeLists.txt
@@ -67,24 +67,20 @@
 
 enable_testing()
 
-# Function to resolve both config and generate stage variables.
-macro(generate_config INPUT TEMP OUTPUT)
-    configure_file(${INPUT} ${TEMP})
-    file(GENERATE OUTPUT ${OUTPUT}
-      INPUT ${TEMP}
-      CONDITION 1
-    )
-endmacro()
-
-# Add lazy loaded shared library paths to test environment
-foreach( lib SQLite::sqlite3 )
-  get_target_property(library_path ${lib} INTERFACE_LIBRARY_DIR)
-  set(LD_LIBRARY_PATH ${LD_LIBRARY_PATH} ${library_path})
-  get_target_property(runtime_path ${lib} INTERFACE_RUNTIME_DIR)
-  set(PATH ${PATH} ${runtime_path})
-endforeach()
-
-set (PORT 20000)
+set(LIBRARY_PATH_ENVIRONMENT_VARIABLE LD_LIBRARY_PATH)
+if (APPLE)
+  set(LIBRARY_PATH_ENVIRONMENT_VARIABLE DYLD_LIBRARY_PATH)
+elseif(WIN32)
+  set(LIBRARY_PATH_ENVIRONMENT_VARIABLE PATH)
+endif()
+set(LIBRARY_PATH
+  $<TARGET_LINKER_FILE_DIR:apache-geode>
+  $<TARGET_LINKER_FILE_DIR:SqLiteImpl>
+  $<TARGET_PROPERTY:SQLite::sqlite3,INTERFACE_LIBRARY_DIR>
+  $<TARGET_PROPERTY:SQLite::sqlite3,INTERFACE_RUNTIME_DIR>
+  $<TARGET_LINKER_FILE_DIR:unit_test_callbacks>
+  $<TARGET_LINKER_FILE_DIR:testobject>
+)
 
 add_custom_target(cppcache-integration-tests)
 set_target_properties(cppcache-integration-tests PROPERTIES
@@ -98,13 +94,11 @@
 foreach(FILE ${SOURCES})
   string(REGEX REPLACE "\\.cpp" "" TEST ${FILE})
   set(TESTS ${TESTS} ${TEST})
-  add_dependencies(integration-tests ${TEST})
+
   add_executable(${TEST} ${FILE})
-  if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-    target_compile_options(${TEST} PUBLIC
-      -Wno-missing-variable-declarations
-    )
-  endif()
+
+  add_dependencies(integration-tests ${TEST})
+
   set_target_properties(${TEST} PROPERTIES
     CXX_VISIBILITY_PRESET hidden
     VISIBILITY_INLINES_HIDDEN ON
@@ -123,17 +117,22 @@
       testobject
       framework
   )
-  target_include_directories(${TEST} PRIVATE
-    $<TARGET_PROPERTY:apache-geode,SOURCE_DIR>/../src
+
+  target_include_directories(${TEST}
+    PRIVATE
+      $<TARGET_PROPERTY:apache-geode,SOURCE_DIR>/../src
   )
 
   if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
-    target_compile_options(${TEST} PRIVATE
+    target_compile_options(${TEST}
+      PRIVATE
         -Wno-unused-function
     )
   elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
-    target_compile_options(${TEST} PRIVATE
+    target_compile_options(${TEST}
+      PRIVATE
         -Wno-unused-member-function
+        -Wno-missing-variable-declarations
     )
   endif()
 
@@ -143,29 +142,31 @@
   add_clangformat(${TEST})
 
   set(TEST_DIR ${CMAKE_CURRENT_BINARY_DIR}/.tests/${TEST})
-
-  math(EXPR PORT "${PORT} + 1")
-
-  if (WIN32)
-    set (TEST_SCRIPT_SUFFIX .bat)
-    generate_config(${CMAKE_CURRENT_SOURCE_DIR}/test.bat.in ${CMAKE_CURRENT_BINARY_DIR}/.${TEST}.bat.in $<TARGET_FILE:${TEST}>${TEST_SCRIPT_SUFFIX})
-
-    set(TEST_COMMAND $<TARGET_FILE:${TEST}>${TEST_SCRIPT_SUFFIX})
-
-  else()
-    set (TEST_SCRIPT_SUFFIX .sh)
-    generate_config(${CMAKE_CURRENT_SOURCE_DIR}/test.sh.in ${CMAKE_CURRENT_BINARY_DIR}/.${TEST}.sh.in $<TARGET_FILE:${TEST}>${TEST_SCRIPT_SUFFIX})
-
-    # TODO fix file permissions on .sh
-    set(TEST_COMMAND bash $<TARGET_FILE:${TEST}>${TEST_SCRIPT_SUFFIX})
-
-  endif()
+  file(MAKE_DIRECTORY ${TEST_DIR})
 
   add_test(NAME ${TEST}
-      COMMAND ${TEST_COMMAND}
+      COMMAND ${TEST}
+      WORKING_DIRECTORY ${TEST_DIR}
   )
 
-  set_tests_properties(${TEST} PROPERTIES LABELS STABLE)
+  set(ENVIRONMENT
+    TESTNAME=${TEST}
+    "TESTSRC=$<SHELL_PATH:${CMAKE_CURRENT_SOURCE_DIR}>"
+    TIMEBOMB=500
+    MCAST_ADDR=0.0.0.0 # unused but framework expects
+    MCAST_PORT=0       # unused but framework expects
+    GFE_LOGLEVEL=config
+    GFE_SECLOGLEVEL=config
+    "GF_JAVA=$<SHELL_PATH:${Java_JAVA_EXECUTABLE}>"
+    "GFJAVA=$<SHELL_PATH:${Geode_PATH}>"
+    "GF_CLASSPATH=$<SHELL_PATH:${CMAKE_BINARY_DIR}/tests/javaobject/javaobject.jar>"
+    "${LIBRARY_PATH_ENVIRONMENT_VARIABLE}=$<JOIN:$<SHELL_PATH:${LIBRARY_PATH}>,\\$<SEMICOLON>>"
+  )
+
+  set_tests_properties(${TEST} PROPERTIES
+    ENVIRONMENT "${ENVIRONMENT}"
+  )
+
   add_dependencies(cppcache-integration-tests ${TEST})
 endforeach()
 
@@ -174,24 +175,9 @@
 #TODO this is really bad that we include the root of tests
 include_directories(${CMAKE_SOURCE_DIR}/tests/cpp)
 
-set_tests_properties(testDataOutput
-    testFWHelper
-    testSystemProperties
-    testLinkage
-    testRegionTemplateArgs
-    testRegionMap
-    testXmlCacheCreationWithRefid
-    testRegionAttributesFactory
-    testXmlCacheCreationWithOverFlow
-    testThinClientRemoveAllLocal
-    testDunit
-    testSpinLock
-    testSubRegions
-  PROPERTIES
-    LABELS "STABLE;QUICK"
-)
-
-set_tests_properties(testOverflowPutGetSqLite 
+set_tests_properties(
+    # flaky
+    testOverflowPutGetSqLite
     testThinClientAfterRegionLive
     testThinClientCacheables
     testThinClientCq
@@ -233,12 +219,8 @@
     testThinClientTXFailover
     testThinClientTransactionsXA
     testTimedSemaphore
-  PROPERTIES
-    DISABLED TRUE
-    LABELS FLAKY
-)
-
-set_tests_properties(testFwPerf
+    # broken
+    testFwPerf
     testThinClientCqDurable
     testThinClientGatewayTest
     testThinClientHAFailoverRegex
@@ -259,7 +241,6 @@
     testThinClientWriterException
   PROPERTIES
     DISABLED TRUE
-   LABELS OMITTED
 )
 
 add_custom_target(run-cppcache-integration-tests
@@ -270,7 +251,7 @@
 add_dependencies(run-cppcache-integration-tests cppcache-integration-tests)
 add_dependencies(run-integration-tests run-cppcache-integration-tests)
 set_target_properties(run-cppcache-integration-tests PROPERTIES
-    EXCLUDE_FROM_ALL TRUE
-    EXCLUDE_FROM_DEFAULT_BUILD TRUE
+  EXCLUDE_FROM_ALL TRUE
+  EXCLUDE_FROM_DEFAULT_BUILD TRUE
 	FOLDER cpp/test/integration
 )
diff --git a/cppcache/integration-test/comparePerf.pl b/cppcache/integration-test/comparePerf.pl
deleted file mode 100755
index 405c88b..0000000
--- a/cppcache/integration-test/comparePerf.pl
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/perl
-# 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.
-
-# Compare PerfSuite lines in one file against those in another...
-
-$argOne = shift( @ARGV );
-$argTwo = shift( @ARGV );
-
-$argOne =~ s/\\/\//g;
-$argTwo =~ s/\\/\//g;
-
-# Read baseline
-
-if ( ! -f "$argOne" ) {
-  print "Error: No baseline file to for host, checkin appropriate testPutGetPerf.out as file $argOne\n";
-  exit( 1 );
-}
-
-open( FILONE, "grep PerfSuite $argOne|" ) || die( "Error: No baseline file to for host, checkin appropriate testPutGetPerf.out as file $argOne" );
-
-while( $line = <FILONE> ) {
-  $line =~ m/PerfSuite\] (\w+) -- (\d+) ops/;
-  $key = $1;
-  $value = $2;
-  $dataone{"${key}"} = $value;
-}
-
-close( FILONE );
-
-@tmp = keys( %dataone );
-if ( $#tmp == -1 ) {
-  print "Error: No data found in $argOne\n";
-  exit( 1 );
-}
-
-# Read new results
-
-if ( ! -f "$argTwo" ) {
-  print "Error: No result file from test to compare, expected $argTwo\n";
-  exit( 1 );
-}
-
-open( FILTWO, "grep PerfSuite $argTwo|" ) || die( "No file $argTwo" );
-
-while( $line = <FILTWO> ) {
-  $line =~ m/PerfSuite\] (\w+) -- (\d+) ops/;
-  $key = $1;
-  $value = $2;
-  $datatwo{"${key}"} = $value;
-}
-
-close( FILTWO );
-
-$code = 0;
-
-@tmp = keys( %datatwo );
-if ( $#tmp == -1 ) {
-  print "Error: No data found in $argTwo\n";
-  exit( 1 );
-}
-
-# display comparisons
-
-format top =
-%CHANGE  TESTCASE                     BASELINE CURRENT
-======== ============================ ======== ================
-.
-format STDOUT =
-( @##% ) @<<<<<<<<<<<<<<<<<<<<<<<<<<< @####### @####### ops/sec
-$percent, $item,                       $baseValue, $newValue
-.
-
-foreach $item (sort( keys( %dataone ) )) {
-  $change = $datatwo{"${item}"} - $dataone{"${item}"};
-  $percent = int( 100 * ( $change / $dataone{"${item}"} ));
-  $baseValue = $dataone{"${item}"};
-  $newValue = $datatwo{"${item}"};
-  write;
-  if ( $percent < ( -5 ) ) {
-    $code++;
-  }
-}
-
-if ( $code > 0 ) {
-  print "Error: $code performance cases failed by more than 5%\n";
-}
-
-exit( $code );
diff --git a/cppcache/integration-test/test.bat.in b/cppcache/integration-test/test.bat.in
deleted file mode 100644
index 4178a6b..0000000
--- a/cppcache/integration-test/test.bat.in
+++ /dev/null
@@ -1,53 +0,0 @@
-@echo off
-
-rem Licensed to the Apache Software Foundation (ASF) under one or more
-rem contributor license agreements.  See the NOTICE file distributed with
-rem this work for additional information regarding copyright ownership.
-rem The ASF licenses this file to You under the Apache License, Version 2.0
-rem (the "License"); you may not use this file except in compliance with
-rem the License.  You may obtain a copy of the License at
-rem 
-rem      http://www.apache.org/licenses/LICENSE-2.0
-rem 
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-setlocal
-
-set PATH=%PATH%;$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:apache-geode>>
-set PATH=%PATH%;$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:framework>>
-set PATH=%PATH%;$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:testobject>>
-set PATH=%PATH%;$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:SqLiteImpl>>
-set PATH=%PATH%;$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:securityImpl>>
-set PATH=%PATH%;$<SHELL_PATH:$<TARGET_LINKER_FILE_DIR:unit_test_callbacks>>
-set PATH=%PATH%;$<JOIN:$<SHELL_PATH:${PATH}>,;>
-
-set TESTSRC=${CMAKE_CURRENT_SOURCE_DIR}
-set GF_JAVA=$<SHELL_PATH:${Java_JAVA_EXECUTABLE}>
-set GFJAVA=$<SHELL_PATH:${Geode_PATH}>
-set GFE_LOGLEVEL=config
-set GFE_SECLOGLEVEL=config
-set MCAST_ADDR=224.10.13.63
-set MCAST_PORT=${PORT}
-set TIMEBOMB=600
-set GF_CLASSPATH=%GF_CLASSPATH%;${CMAKE_BINARY_DIR}/tests/javaobject/javaobject.jar
-set PROFILERCMD=
-set BUG481=
-set TESTNAME=${TEST}
-
-set
-
-rmdir /q /s "$<SHELL_PATH:${TEST_DIR}>" 2>nul
-mkdir "$<SHELL_PATH:${TEST_DIR}>"
-if %errorlevel% neq 0 exit /b %errorlevel%
-pushd "$<SHELL_PATH:${TEST_DIR}>"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-"$<SHELL_PATH:$<TARGET_FILE:${TEST}>>"
-if %errorlevel% neq 0 exit /b %errorlevel%
-
-popd
-exit /b
diff --git a/cppcache/integration-test/test.sh.in b/cppcache/integration-test/test.sh.in
deleted file mode 100644
index 68abcd1..0000000
--- a/cppcache/integration-test/test.sh.in
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/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.
-
-set -e
-set -o pipefail
-
-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$<TARGET_LINKER_FILE_DIR:apache-geode>
-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$<TARGET_LINKER_FILE_DIR:framework>
-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$<TARGET_LINKER_FILE_DIR:testobject>
-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$<TARGET_LINKER_FILE_DIR:SqLiteImpl>
-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$<TARGET_LINKER_FILE_DIR:securityImpl>
-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$<TARGET_LINKER_FILE_DIR:unit_test_callbacks>
-export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$<JOIN:${LD_LIBRARY_PATH},:>
-
-export TESTSRC=${CMAKE_CURRENT_SOURCE_DIR}
-export GF_JAVA=${Java_JAVA_EXECUTABLE}
-export GFJAVA=${Geode_PATH}
-export GFE_LOGLEVEL=config
-export GFE_SECLOGLEVEL=config 
-export MCAST_ADDR=224.10.13.63
-export MCAST_PORT=${PORT}
-export TIMEBOMB=600
-export GF_CLASSPATH=$GF_CLASSPATH:${CMAKE_BINARY_DIR}/tests/javaobject/javaobject.jar
-export PROFILERCMD=
-export BUG481=
-export TESTNAME=${TEST}
-
-rm -rf "${TEST_DIR}"
-mkdir -p "${TEST_DIR}"
-pushd "${TEST_DIR}"
-
-if [ `uname` = "Darwin" ]; then
-  # export DYLD_LIBRARY_PATH to work around OS X SIP
-  export DYLD_LIBRARY_PATH=$LD_LIBRARY_PATH
-fi
-
-$DEBUG $<TARGET_FILE:${TEST}>
-
-# hack: This is _not_ ideal. We're potentially also masking real product bugs.
-#       For now, we just want something that produces results. TODO: REMOVE ASAP
-if [ `uname` = "SunOS" ]; then
-  (ps auxww | awk '/java .*${TEST}/ {print $2}' | xargs kill -9) 2>/dev/null || true
-else
-  pkill -9 -f 'java .*${TEST}' || true
-fi
-
-popd
diff --git a/cppcache/integration/framework/CMakeLists.txt b/cppcache/integration/framework/CMakeLists.txt
index 5c7476b..50d5865 100644
--- a/cppcache/integration/framework/CMakeLists.txt
+++ b/cppcache/integration/framework/CMakeLists.txt
@@ -55,3 +55,5 @@
     _WarningsAsError
     internal
 )
+
+add_clangformat(integration-framework)
diff --git a/cppcache/integration/framework/Cluster.h b/cppcache/integration/framework/Cluster.h
index c9155d0..01a9393 100644
--- a/cppcache/integration/framework/Cluster.h
+++ b/cppcache/integration/framework/Cluster.h
@@ -128,13 +128,15 @@
           UseIpv6 useIPv6);
 
   Cluster(LocatorCount initialLocators, ServerCount initialServers,
-          std::vector<uint16_t> &locatorPorts, std::vector<uint16_t> &remoteLocatorPort,
+          std::vector<uint16_t> &locatorPorts,
+          std::vector<uint16_t> &remoteLocatorPort,
           uint16_t distributedSystemId);
 
   Cluster(Name name, Classpath classpath, SecurityManager securityManager,
           User user, Password password, LocatorCount initialLocators,
           ServerCount initialServers, CacheXMLFiles cacheXMLFiles,
-          std::vector<uint16_t> &locatorPorts, std::vector<uint16_t> &remoteLocatorPort,
+          std::vector<uint16_t> &locatorPorts,
+          std::vector<uint16_t> &remoteLocatorPort,
           uint16_t distributedSystemId);
 
   Cluster(LocatorCount initialLocators, ServerCount initialServers);
@@ -223,7 +225,6 @@
   bool getUseIPv6();
 
  private:
-
   std::string name_;
   std::string classpath_;
   std::string securityManager_;
diff --git a/cppcache/integration/framework/GfshExecute.cpp b/cppcache/integration/framework/GfshExecute.cpp
index 24ee923..7253062 100644
--- a/cppcache/integration/framework/GfshExecute.cpp
+++ b/cppcache/integration/framework/GfshExecute.cpp
@@ -41,6 +41,7 @@
 using boost::process::environment;
 using boost::process::ipstream;
 using boost::process::std_err;
+using boost::process::std_in;
 using boost::process::std_out;
 
 GfshExecuteException::GfshExecuteException(std::string message, int returnCode)
@@ -112,7 +113,8 @@
   std::lock_guard<std::mutex> guard(g_child_mutex);
 #endif
   return child(getFrameworkString(FrameworkVariable::GfShExecutable),
-               args = commands, env, std_out > outStream, std_err > errStream);
+               args = commands, env, std_out > outStream, std_err > errStream,
+               std_in < boost::process::null);
 }
 
 void GfshExecute::extractConnectionCommand(
diff --git a/examples/cpp/functionexecution/startserver.ps1 b/examples/cpp/functionexecution/startserver.ps1
index 255bab9..5c9042d 100644
--- a/examples/cpp/functionexecution/startserver.ps1
+++ b/examples/cpp/functionexecution/startserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/examples/cpp/functionexecution/stopserver.ps1 b/examples/cpp/functionexecution/stopserver.ps1
index 0b57682..13e5a55 100644
--- a/examples/cpp/functionexecution/stopserver.ps1
+++ b/examples/cpp/functionexecution/stopserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/examples/cpp/sslputget/startserver.ps1 b/examples/cpp/sslputget/startserver.ps1
index 5555d29..d6b1067 100644
--- a/examples/cpp/sslputget/startserver.ps1
+++ b/examples/cpp/sslputget/startserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/examples/cpp/sslputget/stopserver.ps1 b/examples/cpp/sslputget/stopserver.ps1
index fa6e59c..c8904ed 100644
--- a/examples/cpp/sslputget/stopserver.ps1
+++ b/examples/cpp/sslputget/stopserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/examples/dotnet/functionexecution/Program.cs b/examples/dotnet/functionexecution/Program.cs
index a2bff53..ad19a93 100644
--- a/examples/dotnet/functionexecution/Program.cs
+++ b/examples/dotnet/functionexecution/Program.cs
@@ -1,4 +1,4 @@
-﻿/*
+/*
 * 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.
diff --git a/examples/dotnet/functionexecution/startserver.ps1 b/examples/dotnet/functionexecution/startserver.ps1
index bc38327..6885624 100644
--- a/examples/dotnet/functionexecution/startserver.ps1
+++ b/examples/dotnet/functionexecution/startserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/examples/dotnet/functionexecution/stopserver.ps1 b/examples/dotnet/functionexecution/stopserver.ps1
index 742ce8d..74a6c2d 100644
--- a/examples/dotnet/functionexecution/stopserver.ps1
+++ b/examples/dotnet/functionexecution/stopserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/examples/dotnet/sslputget/Program.cs b/examples/dotnet/sslputget/Program.cs
index af7d6ed..c033e69 100644
--- a/examples/dotnet/sslputget/Program.cs
+++ b/examples/dotnet/sslputget/Program.cs
@@ -1,4 +1,4 @@
-﻿/*
+/*
 * 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.
diff --git a/examples/dotnet/sslputget/startserver.ps1 b/examples/dotnet/sslputget/startserver.ps1
index 5555d29..d6b1067 100644
--- a/examples/dotnet/sslputget/startserver.ps1
+++ b/examples/dotnet/sslputget/startserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/examples/dotnet/sslputget/stopserver.ps1 b/examples/dotnet/sslputget/stopserver.ps1
index e2e5719..d457631 100644
--- a/examples/dotnet/sslputget/stopserver.ps1
+++ b/examples/dotnet/sslputget/stopserver.ps1
@@ -1,4 +1,4 @@
-﻿# Licensed to the Apache Software Foundation (ASF) under one or more
+# 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
diff --git a/packer/build-windows-2016-vs-2017.json b/packer/build-windows-2016-vs-2017.json
index 7dacd6a..ee44eff 100644
--- a/packer/build-windows-2016-vs-2017.json
+++ b/packer/build-windows-2016-vs-2017.json
@@ -92,9 +92,7 @@
         "choco install doxygen.install -confirm",
         "choco install openssl -confirm",
         "choco install strawberryperl -confirm",
-        "choco install nuget.commandline -confirm",
-        "# TODO make this a nuget dependency",
-        "choco install nunit.install --version 2.6.4 -confirm"
+        "choco install nuget.commandline -confirm"
       ]
     },
     {
diff --git a/packer/build-windows-2019-vs-2017.json b/packer/build-windows-2019-vs-2017.json
index 72fa19f..29c6969 100644
--- a/packer/build-windows-2019-vs-2017.json
+++ b/packer/build-windows-2019-vs-2017.json
@@ -92,9 +92,7 @@
         "choco install doxygen.install -confirm",
         "choco install openssl -confirm",
         "choco install strawberryperl -confirm",
-        "choco install nuget.commandline -confirm",
-        "# TODO make this a nuget dependency",
-        "choco install nunit.install --version 2.6.4 -confirm"
+        "choco install nuget.commandline -confirm"
       ]
     },
     {
diff --git a/packer/build-windows-2019-vs-2019.json b/packer/build-windows-2019-vs-2019.json
index ffa6653..92fce71 100644
--- a/packer/build-windows-2019-vs-2019.json
+++ b/packer/build-windows-2019-vs-2019.json
@@ -92,9 +92,7 @@
         "choco install doxygen.install -confirm",
         "choco install openssl -confirm",
         "choco install strawberryperl -confirm",
-        "choco install nuget.commandline -confirm",
-        "# TODO make this a nuget dependency",
-        "choco install nunit.install --version 2.6.4 -confirm"
+        "choco install nuget.commandline -confirm"
       ]
     },
     {
diff --git a/templates/security/csharp/CMakeLists.txt b/templates/security/csharp/CMakeLists.txt
index 26751b1..40bc757 100644
--- a/templates/security/csharp/CMakeLists.txt
+++ b/templates/security/csharp/CMakeLists.txt
@@ -4,15 +4,39 @@
 # 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.
-cmake_minimum_required(VERSION 3.4)
-#project(templates.csharp.security)
 
-configure_file(securityImpl.csproj.in ${CMAKE_CURRENT_BINARY_DIR}/securityImpl.csproj)
\ No newline at end of file
+
+project(Apache.Geode.Templates.Cache.Security CSharp)
+
+add_library(Apache.Geode.Templates.Cache.Security SHARED
+  AssemblyInfo.cs
+  UserPasswordAuthInit.cs
+)
+
+target_link_libraries(Apache.Geode.Templates.Cache.Security
+  PUBLIC
+    Apache.Geode
+)
+
+set_target_properties(Apache.Geode.Templates.Cache.Security PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode.Templates.Cache.Security
+  VS_GLOBAL_TreatWarningsAsErrors True
+  VS_GLOBAL_PROJECT_TYPES "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Data"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(Apache.Geode.Templates.Cache.Security PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
+endif()
diff --git a/templates/security/csharp/securityImpl.csproj.in b/templates/security/csharp/securityImpl.csproj.in
deleted file mode 100644
index d547e6a..0000000
--- a/templates/security/csharp/securityImpl.csproj.in
+++ /dev/null
@@ -1,98 +0,0 @@
-<?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.
--->
-<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">X64</Platform>
-    <ProjectGuid>{D9F8A614-D117-491F-9E3A-B5F432E435AE}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Apache.Geode.Templates.Cache.Security</RootNamespace>
-    <AssemblyName>Apache.Geode.Templates.Cache.Security</AssemblyName>
-    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'">
-    <DebugSymbols>true</DebugSymbols>
-    <OutputPath>bin\x64\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
-    <OutputPath>bin\x64\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64'">
-    <OutputPath>bin\x64\RelWithDebInfo\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Apache.Geode.Client">
-      <HintPath>${GEODE_NATIVE_HOME}\bin\Apache.Geode.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="System.Data.DataSetExtensions" />
-    <Reference Include="Microsoft.CSharp" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="${CMAKE_SOURCE_DIR}\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="${CMAKE_SOURCE_DIR}\UserPasswordAuthInit.cs">
-      <Link>UserPasswordAuthInit.cs</Link>
-    </Compile>    
-  </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Properties\" />
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PostBuildEvent>copy $(TargetPath) ${GEODE_NATIVE_HOME}\bin\$(TargetFileName)</PostBuildEvent>
-  </PropertyGroup>  
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/tests/cli/CMakeLists.txt b/tests/cli/CMakeLists.txt
index 1d81e62..ff8033b 100644
--- a/tests/cli/CMakeLists.txt
+++ b/tests/cli/CMakeLists.txt
@@ -13,42 +13,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cmake_minimum_required(VERSION 3.10)
-project(nativeclient.tests LANGUAGES NONE)
-
+add_subdirectory(DUnitFramework)
+add_subdirectory(FwkClient)
 add_subdirectory(QueryHelper)
 add_subdirectory(PdxClassLibrary)
+add_subdirectory(NewTestObject)
+add_subdirectory(PdxVersion1Lib)
+add_subdirectory(PdxVersion2Lib)
+add_subdirectory(SecurityUtil)
 
-set (NUNIT "C:\\Program Files (x86)\\NUnit 2.6.4")
-
-if (64 EQUAL ${BUILD_BITS})
-  set (NUNIT_CONSOLE "nunit-console")
-  set (PLATFORM x64)
-else()
-  set (NUNIT_CONSOLE "nunit-console-x86")
-  set (PLATFORM x86)
-endif()
-
-# Set the .NET Target Framework (Note: This should match the build for Apache.Geode.)
-
-foreach(var CMAKE_CURRENT_SOURCE_DIR CMAKE_SOURCE_DIR CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR)
-  file(TO_NATIVE_PATH ${${var}} ${var}_NATIVE)
-endforeach()
-
-file(GLOB_RECURSE CSPROJECTS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.csproj.in")
-if(EXISTS "${STRONG_NAME_KEY}")
-  set(STRONG_NAME_KEY_ENABLED true)
-endif()
-
-foreach(FILE ${CSPROJECTS})
-  # TODO: make this a one line MATCH statement
-  string(REGEX REPLACE "\\.csproj.in" "" PROJDIR ${FILE})
-  string(REGEX REPLACE ".*/" "" PROJNAME ${PROJDIR})
-  configure_file(${FILE} ${CMAKE_CURRENT_BINARY_DIR}/${PROJNAME}/${PROJNAME}.csproj)
-  include_external_msproject(
-      ${PROJNAME}  ${CMAKE_CURRENT_BINARY_DIR}/${PROJNAME}/${PROJNAME}.csproj
-      TYPE FAE04EC0-301F-11D3-BF4B-00C04F79EFBC
-	  PLATFORM ${PLATFORM})
-  set_target_properties(${PROJNAME} PROPERTIES FOLDER cli/test/integration)
-
-endforeach()
diff --git a/tests/cli/DUnitFramework/CMakeLists.txt b/tests/cli/DUnitFramework/CMakeLists.txt
new file mode 100644
index 0000000..6202fc2
--- /dev/null
+++ b/tests/cli/DUnitFramework/CMakeLists.txt
@@ -0,0 +1,61 @@
+# 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.
+
+cmake_minimum_required( VERSION 3.15 )
+project(DUnitFramework CSharp)
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages.config ${CMAKE_CURRENT_BINARY_DIR}/packages.config COPYONLY)
+
+add_library(DUnitFramework SHARED
+  packages.config
+  AssemblyInfo.cs
+  ClientBase.cs
+  ClientGroup.cs
+  CMakeLists.txt
+  DUnitTestClass.cs
+  Exceptions.cs
+  IClientServerComm.cs
+  Log.cs
+  ServerCommunication.cs
+  ServerConnection.cs
+  TimeBomb.cs
+  UnitProcess.cs
+  UnitThread.cs
+  Util.cs
+  XmlNodeReaderWriter.cs
+)
+
+target_link_libraries(DUnitFramework
+  PUBLIC
+    Apache.Geode
+)
+
+set_target_properties(DUnitFramework PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode.DUnitFramework
+  VS_GLOBAL_TreatWarningsAsErrors True
+  VS_GLOBAL_PROJECT_TYPES "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Runtime.Remoting;System.Management"
+  VS_DOTNET_REFERENCE_NUnit "${CMAKE_BINARY_DIR}/packages/NUnit.2.6.4/lib/nunit.framework.dll"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(DUnitFramework PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
+endif()
+
+add_dependencies(DUnitFramework nuget-restore)
diff --git a/tests/cli/DUnitFramework/DUnitFramework.csproj.in b/tests/cli/DUnitFramework/DUnitFramework.csproj.in
deleted file mode 100755
index aa7c750..0000000
--- a/tests/cli/DUnitFramework/DUnitFramework.csproj.in
+++ /dev/null
@@ -1,156 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-    <CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-    <CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{B2F8AE2D-3E73-3A99-BFD2-FF0B7B55C780}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Apache.Geode.DUnitFramework</RootNamespace>
-    <AssemblyName>DUnitFramework</AssemblyName>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="nunit.framework">
-      <HintPath>${NUNIT}\bin\framework\nunit.framework.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.Management" />
-    <Reference Include="System.Runtime.Remoting" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\ClientBase.cs">
-      <Link>ClientBase.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\ClientGroup.cs">
-      <Link>ClientGroup.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\DUnitTestClass.cs">
-      <Link>DUnitTestClass.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\Exceptions.cs">
-      <Link>Exceptions.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\IClientServerComm.cs">
-      <Link>IClientServerComm.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\Log.cs">
-      <Link>Log.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\ServerCommunication.cs">
-      <Link>ServerCommunication.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\ServerConnection.cs">
-      <Link>ServerConnection.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\TimeBomb.cs">
-      <Link>TimeBomb.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\UnitProcess.cs">
-      <Link>UnitProcess.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\UnitThread.cs">
-      <Link>UnitThread.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\Util.cs">
-      <Link>Util.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\DUnitFramework\XmlNodeReaderWriter.cs">
-      <Link>XmlNodeReaderWriter.cs</Link>
-    </Compile>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/tests/cli/DUnitFramework/packages.config b/tests/cli/DUnitFramework/packages.config
new file mode 100644
index 0000000..47b176b
--- /dev/null
+++ b/tests/cli/DUnitFramework/packages.config
@@ -0,0 +1,20 @@
+<?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.
+-->
+<packages>
+  <package id="NUnit" version="2.6.4" targetFramework="net35" />
+</packages>
diff --git a/tests/cli/FwkClient/CMakeLists.txt b/tests/cli/FwkClient/CMakeLists.txt
new file mode 100644
index 0000000..90ddcd3
--- /dev/null
+++ b/tests/cli/FwkClient/CMakeLists.txt
@@ -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.
+
+cmake_minimum_required( VERSION 3.15 )
+project(FwkClient CSharp)
+
+add_executable(FwkClient
+  AssemblyInfo.cs
+  ClientComm.cs
+  ClientProcess.cs
+  App.config
+)
+
+target_link_libraries(FwkClient
+  PUBLIC
+    DUnitFramework
+)
+
+set_target_properties(FwkClient PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode.Client.FwkClient
+  VS_GLOBAL_TreatWarningsAsErrors True
+  VS_GLOBAL_PROJECT_TYPES "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Runtime.Remoting;System.Management"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(FwkClient PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
+endif()
diff --git a/tests/cli/FwkClient/FwkClient.csproj.in b/tests/cli/FwkClient/FwkClient.csproj.in
deleted file mode 100644
index 9a2ef5b..0000000
--- a/tests/cli/FwkClient/FwkClient.csproj.in
+++ /dev/null
@@ -1,122 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-    <CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-    <CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{0A33CB39-D33F-39B2-BB11-B0A555805177}</ProjectGuid>
-    <OutputType>Exe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Apache.Geode.Client.FwkClient</RootNamespace>
-    <AssemblyName>FwkClient</AssemblyName>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <Optimize>false</Optimize>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Runtime.Remoting" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\FwkClient\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\FwkClient\ClientComm.cs">
-      <Link>ClientComm.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\FwkClient\ClientProcess.cs">
-      <Link>ClientProcess.cs</Link>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\DUnitFramework\DUnitFramework.csproj">
-      <Project>{796727E8-3A6A-46BE-A2DB-584A4774CD51}</Project>
-      <Name>DUnitFramework</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target> -->
-  <!--<Target Name="AfterBuild">
-    <Copy SourceFiles="$(OSBUILDDIR)\tests\clicache\FwkClient\FwkClient.exe.config" DestinationFolder="$(OSBUILDDIR)\tests\clicache\UnitTests" />
-  </Target>-->
-</Project>
diff --git a/tests/cli/FwkLauncher/FwkLauncher.csproj.in b/tests/cli/FwkLauncher/FwkLauncher.csproj.txt
similarity index 100%
rename from tests/cli/FwkLauncher/FwkLauncher.csproj.in
rename to tests/cli/FwkLauncher/FwkLauncher.csproj.txt
diff --git a/tests/cli/FwkUtil/FwkUtil.csproj.in b/tests/cli/FwkUtil/FwkUtil.csproj.txt
similarity index 100%
rename from tests/cli/FwkUtil/FwkUtil.csproj.in
rename to tests/cli/FwkUtil/FwkUtil.csproj.txt
diff --git a/tests/cli/NewFwkLib/AssemblyInfo.cs b/tests/cli/NewFwkLib/AssemblyInfo.cs
deleted file mode 100644
index 58af713..0000000
--- a/tests/cli/NewFwkLib/AssemblyInfo.cs
+++ /dev/null
@@ -1,49 +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.
- */
-
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("NewFwkLib")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyProduct("NewFwkLib")]
-[assembly: AssemblyCopyright("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.")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("9d51841c-4400-4bb4-95c9-15a8e6c14b38")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/tests/cli/NewFwkLib/CacheHelper.cs b/tests/cli/NewFwkLib/CacheHelper.cs
deleted file mode 100644
index 8c178c0..0000000
--- a/tests/cli/NewFwkLib/CacheHelper.cs
+++ /dev/null
@@ -1,482 +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.
- */
-
-using System;
-using System.Diagnostics;
-using System.IO;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Xml;
-
-#pragma warning disable 618
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-  //using Region = Apache.Geode.Client.IRegion<Object, Object>;
-  //using IntRegion = Apache.Geode.Client.IRegion<int, byte[]>;
-  //using StringRegion = Apache.Geode.Client.IRegion<string, byte[]>;
-  using VMW = Apache.Geode.Client;
-  public class PropsStringToObject
-  {
-    public PropsStringToObject(Properties<string, object> target)
-    {
-      m_target = target;
-    }
-
-    public void Visit(string key, string val)
-    {
-      if (key == "security-signature")
-      {
-        string[] stringbytes = val.Split(' ');
-        byte[] credentialbytes = new byte[stringbytes.Length - 1];
-        int position = 0;
-        foreach (string item in stringbytes)
-        {
-          if (string.IsNullOrEmpty(item)) continue;
-          credentialbytes[position++] = byte.Parse(item);
-        }
-        m_target.Insert(key, credentialbytes);
-      }
-      else
-      {
-        m_target.Insert(key, val);
-      }
-    }
-    private Properties<string, object> m_target;
-  }
-
-  public class PropsObjectToObject
-  {
-    public PropsObjectToObject(Properties<string, object> target)
-    {
-      m_target = target;
-    }
-
-    public void Visit(string key, object val)
-    {
-      if (key == "security-signature")
-      {
-        string strval = (string)val;
-        string[] stringbytes = strval.Split(' ');
-        byte[] credentialbytes = new byte[stringbytes.Length - 1];
-        int position = 0;
-        foreach (string item in stringbytes)
-        {
-          if (string.IsNullOrEmpty(item)) continue;
-          credentialbytes[position++] = byte.Parse(item);
-        }
-        m_target.Insert(key, credentialbytes);
-      }
-      else
-      {
-        m_target.Insert(key, val);
-      }
-    }
-    private Properties<string, object> m_target;
-  }
-
-  /// <summary>
-  /// Helper class to create/destroy Distributed System, cache and regions.
-  /// This class is intentionally not thread-safe.
-  /// </summary>
-  public class CacheHelper<TKey, TVal>
-  {
-    #region Private static members and constants
-
-    private static Cache m_cache = null;
-    private static IRegion<TKey,TVal> m_currRegion = null;
-
-    private const string DefaultDSName = "dstest";
-    private const string DefaultCacheName = "cachetest";
-
-    private static char PathSep = Path.DirectorySeparatorChar;
-    #endregion
-
-    #region Private Utility functions
-
-
-    private static void FwkInfo(string message)
-    {
-      if (FwkTest<TKey, TVal>.CurrentTest != null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo(message);
-      }
-    }
-
-    private static void FwkInfo(string fmt, params object[] paramList)
-    {
-      if (FwkTest<TKey, TVal>.CurrentTest != null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo(fmt, paramList);
-      }
-    }
-
-    private static void FwkAssert(bool condition, string message)
-    {
-      if (FwkTest<TKey, TVal>.CurrentTest != null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkAssert(condition, message);
-      }
-    }
-
-    private static void FwkAssert(bool condition, string fmt,
-      params object[] paramList)
-    {
-      if (FwkTest<TKey, TVal>.CurrentTest != null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkAssert(condition, fmt, paramList);
-      }
-    }
-
-    #endregion
-
-    #region Public accessors
-
-    public static Cache DCache
-    {
-      get
-      {
-        return m_cache;
-      }
-      set
-      {
-        m_cache = value;
-      }
-    }
-    public static IRegion<TKey,TVal> CurrentRegion
-    {
-      get
-      {
-        return m_currRegion;
-      }
-    }
-
-    #endregion
-
-    #region Functions to initialize or close a cache and distributed system
-
-
-    public static void Init()
-    {
-      InitConfig(null, null, false);
-    }
-    public static Properties<string, object> GetPkcsCredentialsForMU(Properties<string, string> credentials)
-    {
-      if (credentials == null)
-        return null;
-      var target = Properties<string, object>.Create();
-      var psto = new PropsStringToObject(target);
-      credentials.ForEach(new PropertyVisitorGeneric<string, string>(psto.Visit));
-      return target;
-    }
-    public static Properties<string, object> GetPkcsCredentialsForMU(Properties<string, object> credentials)
-    {
-      if (credentials == null)
-        return null;
-      var target = Properties<string, object>.Create();
-      var poto = new PropsObjectToObject(target);
-      credentials.ForEach(new PropertyVisitorGeneric<string, object>(poto.Visit));
-      return target;
-    }
-
-    public static void InitConfig(Properties<string,string> config)
-    {
-      InitConfig(config, null, false);
-    }
-
-    public static void InitConfigPdxReadSerialized(Properties<string, string> dsProps, bool PdxReadSerialized)
-    {
-      InitConfig(dsProps, null, PdxReadSerialized);
-    }
-
-    public static void InitConfigPool(Properties<string,string> dsProps)
-    {
-      InitConfig(dsProps, null, false);
-    }
-
-    public static void InitConfig(string cacheXml)
-    {
-      InitConfig(null, cacheXml, false);
-    }
-
-    public static void InitConfig(Properties<string,string> config,
-      string cacheXml, bool PdxReadSerialized)
-    {
-      string geodeNativePropsFile = Util.AssemblyDir + "/geode.properties";
-      if (File.Exists(geodeNativePropsFile))
-      {
-        Properties<string,string> newConfig = new Properties<string,string>();
-        newConfig.Load(geodeNativePropsFile);
-        if (config != null)
-        {
-          newConfig.AddAll(config);
-        }
-        config = newConfig;
-      }
-      //ConnectConfig(dsName, config);
-      if (m_cache == null || m_cache.IsClosed)
-      {
-        try
-        {
-          CacheFactory cf = new CacheFactory(config);
-
-          if (cacheXml != null && cacheXml.Length > 0)
-          {
-            FwkInfo("seting cache-xml-file {0}", cacheXml);
-            cf = cf.Set("cache-xml-file", cacheXml);
-          }
-          
-          if (PdxReadSerialized)
-          {
-            FwkInfo("seting PdxReadSerialized {0}", PdxReadSerialized);
-            cf = new CacheFactory(config)
-                .SetPdxReadSerialized(PdxReadSerialized);
-          }
-          
-          m_cache = cf.Create();
-        }
-        catch (CacheExistsException)
-        {
-          m_cache = new CacheFactory(config).Create();
-        }
-      }
-
-    }
-
-    public static void InitConfigForPoolDurable(string durableClientId, int durableTimeout, string conflateEvents, bool isSslEnable)
-    {
-      Properties<string,string> config = new Properties<string,string>();
-      config.Insert("durable-client-id", durableClientId);
-      config.Insert("durable-timeout", durableTimeout.ToString() + "s");
-      if (conflateEvents != null && conflateEvents.Length > 0)
-      {
-        config.Insert("conflate-events", conflateEvents);
-      }
-      if (isSslEnable)
-      {
-        config.Insert("ssl-enabled", "true");
-        string keyStorePath = Util.GetFwkLogDir(Util.SystemType) + "/data/keystore";
-        string pubkey = keyStorePath + "/client_truststore.pem";
-        string privkey = keyStorePath + "/client_keystore.pem";
-        config.Insert("ssl-keystore", privkey);
-        config.Insert("ssl-truststore", pubkey);
-      }
-      InitConfig(config, null,false);
-
-    }
-    public static void InitClient()
-    {
-      CacheHelper<TKey, TVal>.Close();
-      Properties<string,string> config = new Properties<string,string>();
-      CacheHelper<TKey, TVal>.InitConfig(config);
-    }
-
-    public static void Close()
-    {
-      CloseCache();
-    }
-
-    public static void CloseCache()
-    {
-      if (m_cache != null && !m_cache.IsClosed)
-      {
-        m_cache.Close();
-      }
-      m_cache = null;
-    }
-
-    public static void CloseKeepAlive()
-    {
-      CloseCacheKeepAlive();
-    }
-
-    public static void CloseCacheKeepAlive()
-    {
-      if (m_cache != null && !m_cache.IsClosed)
-      {
-        m_cache.Close(true);
-      }
-      m_cache = null;
-    }
-
-    #endregion
-
-    #region Functions to create or destroy a region
-
-    public static IRegion<TKey, TVal> CreateRegion(string name, RegionFactory attrs)
-    {
-
-      Init();
-      DestroyRegion(name, true, false);
-      IRegion<TKey, TVal> region = attrs.Create<TKey, TVal>(name);
-      FwkAssert(region != null, "Region {0} was not created.", name);
-      m_currRegion = region;
-      return region;
-    }
-    
-    public static void DestroyRegion(string name, bool local, bool verify)
-    {
-      IRegion<TKey, TVal> region;
-      if (verify)
-      {
-        region = GetVerifyRegion(name);
-      }
-      else
-      {
-        region = GetRegion(name);
-      }
-      if (region != null)
-      {
-        if (local)
-        {
-          region.GetLocalView().DestroyRegion();
-        }
-        else
-        {
-          region.DestroyRegion();
-        }
-      }
-    }
-    
-    public static void DestroyAllRegions(bool local)
-    {
-      if (m_cache != null && !m_cache.IsClosed)
-      {
-        IRegion<TKey, TVal>[] regions = m_cache.RootRegions<TKey, TVal>();
-        if (regions != null)
-        {
-          foreach (IRegion<TKey, TVal> region in regions)
-          {
-            if (local)
-            {
-              region.GetLocalView().DestroyRegion();
-            }
-            else
-            {
-              region.DestroyRegion();
-            }
-          }
-        }
-      } 
-    }
-    public static void SetDCacheNull()
-    {
-      m_cache = null;
-    }
-    #endregion
-
-    #region Functions to obtain a region
-   
-    public static IRegion<TKey, TVal> GetRegion(string path)
-    {
-
-      if (m_cache != null)
-      {
-        return m_cache.GetRegion<TKey,TVal>(path);
-      }
-      return null;
-    }
-    
-    public static IRegion<TKey, TVal> GetVerifyRegion(string path)
-    {
-      IRegion<TKey, TVal> region = GetRegion(path);
-      FwkAssert(region != null, "Region [" + path + "] not found.");
-      FwkInfo("Found region '{0}'", path);
-      return region;
-    }
-    
-    #endregion
-
-    #region Utility functions
-
-    public static void LogKeys(ICacheableKey[] cKeys)
-    {
-      if (cKeys != null)
-      {
-        for (int i = 0; i < cKeys.Length; i++)
-        {
-          FwkInfo("Key [{0}] = {1}", i, cKeys[i]);
-        }
-      }
-    }
-
-    public static void LogValues(ISerializable[] cValues)
-    {
-      if (cValues != null)
-      {
-        for (int i = 0; i < cValues.Length; i++)
-        {
-          FwkInfo("Value [{0}] = {1}", i, cValues[i]);
-        }
-      }
-    }
-
-    public static string RegionTag(Apache.Geode.Client.RegionAttributes<TKey, TVal> attrs)
-    {
-      string tag = string.Empty;
-      tag += attrs.CachingEnabled ? "Caching" : "NoCache";
-      tag += (attrs.CacheListener == null) ? "Nlstnr" : "Lstnr";
-      return tag;
-    }
-
-    public static string RegionAttributesToString(Apache.Geode.Client.RegionAttributes<TKey, TVal> attrs)
-    {
-      StringBuilder attrsSB = new StringBuilder();
-      attrsSB.Append(Environment.NewLine + "caching: " +
-        attrs.CachingEnabled);
-      attrsSB.Append(Environment.NewLine + "pool: " +
-        attrs.PoolName);
-       attrsSB.Append(Environment.NewLine + "initialCapacity: " +
-        attrs.InitialCapacity);
-      attrsSB.Append(Environment.NewLine + "loadFactor: " +
-        attrs.LoadFactor);
-      attrsSB.Append(Environment.NewLine + "concurrencyLevel: " +
-        attrs.ConcurrencyLevel);
-      attrsSB.Append(Environment.NewLine + "lruEntriesLimit: " +
-        attrs.LruEntriesLimit);
-      attrsSB.Append(Environment.NewLine + "lruEvictionAction: " +
-        attrs.LruEvictionAction);
-      attrsSB.Append(Environment.NewLine + "entryTimeToLive: " +
-        attrs.EntryTimeToLive);
-      attrsSB.Append(Environment.NewLine + "entryTimeToLiveAction: " +
-        attrs.EntryTimeToLiveAction);
-      attrsSB.Append(Environment.NewLine + "entryIdleTimeout: " +
-        attrs.EntryIdleTimeout);
-      attrsSB.Append(Environment.NewLine + "entryIdleTimeoutAction: " +
-        attrs.EntryIdleTimeoutAction);
-      attrsSB.Append(Environment.NewLine + "regionTimeToLive: " +
-        attrs.RegionTimeToLive);
-      attrsSB.Append(Environment.NewLine + "regionTimeToLiveAction: " +
-        attrs.RegionTimeToLiveAction);
-      attrsSB.Append(Environment.NewLine + "regionIdleTimeout: " +
-        attrs.RegionIdleTimeout);
-      attrsSB.Append(Environment.NewLine + "regionIdleTimeoutAction: " +
-        attrs.RegionIdleTimeoutAction);
-      attrsSB.AppendFormat("{0}cacheLoader: {1}",Environment.NewLine, attrs.CacheLoader != null ? "Enabled" : "Disabled");
-      attrsSB.AppendFormat("{0}cacheWriter: {1}", Environment.NewLine,attrs.CacheWriter != null ? "Enabled" : "Disabled");
-      attrsSB.AppendFormat("{0}cacheListener: {1}", Environment.NewLine, attrs.CacheListener != null ? "Enabled" : "Disabled");
-      attrsSB.Append(Environment.NewLine + "concurrency-checks-enabled: " +
-        attrs.ConcurrencyChecksEnabled);
-      attrsSB.Append(Environment.NewLine);
-      return attrsSB.ToString();
-    }
-
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/CacheServer.cs b/tests/cli/NewFwkLib/CacheServer.cs
deleted file mode 100644
index afa1025..0000000
--- a/tests/cli/NewFwkLib/CacheServer.cs
+++ /dev/null
@@ -1,4890 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.Reflection;
-using System.IO;
-using PdxTests;
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-  using QueryCategory = Apache.Geode.Client.Tests.QueryCategory;
-  using QueryStrings = Apache.Geode.Client.Tests.QueryStrings;
-  using QueryStatics = Apache.Geode.Client.Tests.QueryStatics;
-
-  public class SilenceListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>
-  {
-
-      long currentTimeInMillies()
-      {
-          long curruntMillis = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-          return curruntMillis;
-      }
-    public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-
-      Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-    }
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-    }
-    public override void AfterDestroy(EntryEvent<TKey, TVal> ev)
-    {
-      Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-    }
-    public override void AfterInvalidate(EntryEvent<TKey, TVal> ev)
-    {
-      Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-    }
-  }
-  
-  public class MyCqListener<TKey, TResult> : ICqListener<TKey, TResult>
-  {
-    private UInt32 m_updateCnt;
-    private UInt32 m_createCnt;
-    private UInt32 m_destroyCnt;
-    private UInt32 m_eventCnt;
-
-    public MyCqListener()
-    {
-      m_updateCnt = 0;
-      m_createCnt = 0;
-      m_destroyCnt = 0;
-      m_eventCnt = 0;
-    }
-
-    public UInt32 NumInserts()
-    {
-      return m_createCnt;
-    }
-
-    public UInt32 NumUpdates()
-    {
-      return m_updateCnt;
-    }
-
-    public UInt32 NumDestroys()
-    {
-      return m_destroyCnt;
-    }
-
-    public UInt32 NumEvents()
-    {
-      return m_eventCnt;
-    }
-
-    public virtual void UpdateCount(CqEvent<TKey, TResult> ev)
-    {
-      m_eventCnt++;
-      CqOperation opType = ev.getQueryOperation();
-      if (opType == CqOperation.OP_TYPE_CREATE)
-      {
-        m_createCnt++;
-       // Util.Log("m_create is {0}",m_createCnt);
-      }
-      else if (opType == CqOperation.OP_TYPE_UPDATE)
-      {
-        m_updateCnt++;
-       // Util.Log("m_create is {0}", m_updateCnt);
-      }
-      else if (opType == CqOperation.OP_TYPE_DESTROY)
-      {
-        m_destroyCnt++;
-      //  Util.Log("m_create is {0}", m_destroyCnt);
-      }
-
-    }
-    public virtual void OnError(CqEvent<TKey, TResult> ev)
-    {
-      UpdateCount(ev);
-    }
-
-    public virtual void OnEvent(CqEvent<TKey, TResult> ev)
-    {
-      UpdateCount(ev);
-    }
-
-    public virtual void Close()
-    {
-    }
-  }
-  //----------------------------------- DoOpsTask start ------------------------
-    public class DoOpsTask<TKey, TVal> : ClientTask
-    {
-        private IRegion<TKey, TVal> m_region;
-        private  const int INVALIDATE             = 1;
-        private  const int LOCAL_INVALIDATE       = 2;
-        private  const int DESTROY                = 3;
-        private  const int LOCAL_DESTROY          = 4;
-        private  const int UPDATE_EXISTING_KEY    = 5;
-        private  const int GET                    = 6;
-        private  const int ADD_NEW_KEY            = 7;
-        private  const int PUTALL_NEW_KEY         = 8;
-        private  const int NUM_EXTRA_KEYS = 100;
-        private static bool m_istransaction = false;
-        CacheTransactionManager txManager = null;
-        private object CLASS_LOCK = new object();
-        private static string m_sharePath;
-        //Assembly m_pdxVersionOneAsm;
-        //Assembly m_pdxVersionTwoAsm;
-        protected int[] operations = { INVALIDATE, LOCAL_INVALIDATE, DESTROY, LOCAL_DESTROY, UPDATE_EXISTING_KEY, GET, ADD_NEW_KEY, PUTALL_NEW_KEY };
-        public DoOpsTask(IRegion<TKey, TVal> region, bool istransaction)
-            : base()
-        {
-            m_region = region;
-            m_istransaction = istransaction;
-            if(m_istransaction)
-                txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-
-        }
-        public override void DoTask(int iters, object data)
-        {
-            Random random = new Random();
-            List<int> availableOps = new List<int>(operations);
-            if (m_istransaction)
-            {
-               availableOps.Remove(LOCAL_DESTROY);
-               availableOps.Remove(LOCAL_INVALIDATE);
-            }
-            while (Running && (availableOps.Count != 0))
-            {
-                int opcode = -1;
-                lock (CLASS_LOCK)
-                {
-                    bool doneWithOps = false;
-                    int i = random.Next(0, availableOps.Count);
-                    //try
-                    //{
-                        opcode = availableOps[i];
-                        if (m_istransaction)
-                        {
-                            //txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-                            txManager.Begin();
-                        }
-                        switch (opcode)
-                        {
-                            case ADD_NEW_KEY:
-                                doneWithOps = addNewKey();
-                                break;
-                            case PUTALL_NEW_KEY:
-                                doneWithOps = putAllNewKey();
-                                break;
-                            case INVALIDATE:
-                                doneWithOps = invalidate();
-                                break;
-                            case DESTROY:
-                                doneWithOps = destroy();
-                                break;
-                            case UPDATE_EXISTING_KEY:
-                                doneWithOps = updateExistingKey();
-                                break;
-                            case GET:
-                                doneWithOps = get();
-                                break;
-                            case LOCAL_INVALIDATE:
-                                doneWithOps = localInvalidate();
-                                break;
-                            case LOCAL_DESTROY:
-                                doneWithOps = localDestroy();
-                                break;
-                            default:
-                                {
-                                    throw new Exception("Invalid operation specified:" + opcode);
-                                }
-                        }
-                        if (m_istransaction)// && (!doneWithOps))
-                        {
-                            try
-                            {
-                                txManager.Commit();
-                            }
-                           catch (CommitConflictException ex)
-                            {
-                                string errStr = ex.ToString();
-                                if ((errStr.IndexOf("REMOVED") >= 0) ||
-                                    (errStr.IndexOf("INVALID") >= 0) ||
-                                    (errStr.IndexOf("Deserializ") >= 0))
-                                {
-                                    throw new Exception("Test got " + errStr + ", but this error text " +
-                                          "might contain Geode internal values\n" + ex.Message);
-                                }
-                            }
-                           
-                        }
-                    
-                    if (doneWithOps)
-                    {
-                        availableOps.Remove(opcode);
-                    }
-                }
-            }
-         } //end doTask function
-
-         private TVal GetValue()
-         {
-             return GetValue(null);
-         }
-
-         private TVal GetValue(object value)
-         {
-             TVal tmpValue = default(TVal);
-             FwkTest<TKey, TVal>.CurrentTest.ResetKey("valueSizes");
-             int size = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("valueSizes");
-             StringBuilder builder = new StringBuilder();
-             Random random = new Random();
-             char ch;
-             for (int j = 0; j < size; j++)
-             {
-                 ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
-                 builder.Append(ch);
-             }
-             FwkTest<TKey, TVal>.CurrentTest.ResetKey("objectType");
-             string m_objectType = FwkTest<TKey, TVal>.CurrentTest.GetStringValue("objectType");
-             FwkTest<TKey, TVal>.CurrentTest.ResetKey("versionNum");
-             int m_versionNum = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("versionNum"); //random.Next(2) + 1;// (counter++ % 2) + 1;
-             string sharedpath = (string)Util.BBGet("SharedPath", "sharedDir");
-             m_sharePath = Path.Combine(sharedpath, "framework/csharp/bin");
-             if (typeof(TVal) == typeof(string))
-             {
-                 tmpValue = (TVal)(object)builder.ToString();
-             }
-             else if (typeof(TVal) == typeof(byte[]))
-             {
-                 tmpValue = (TVal)(object)(Encoding.ASCII.GetBytes(builder.ToString()));
-             }
-             else if (m_objectType != null)
-             {
-                 if (m_objectType.Equals("PdxVersioned") && m_versionNum == 1)
-                 {
-                     PdxTests<TKey, TVal>.m_pdxVersionOneAsm = Assembly.LoadFrom(Path.Combine(m_sharePath, "PdxVersion1Lib.dll"));
-                     Type pt = PdxTests<TKey, TVal>.m_pdxVersionOneAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-                     tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, new object[] { value.ToString() });
-                 }
-                 else if (m_objectType.Equals("PdxVersioned") && m_versionNum == 2)
-                 {
-                     PdxTests<TKey, TVal>.m_pdxVersionTwoAsm = Assembly.LoadFrom(Path.Combine(m_sharePath, "PdxVersion2Lib.dll"));
-                     Type pt = PdxTests<TKey, TVal>.m_pdxVersionTwoAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-                     tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, new object[] { value.ToString() });
-                 }
-                 else if (m_objectType.Equals("Nested"))
-                 {
-
-                     tmpValue = (TVal)(object)new NestedPdx();
-                 }
-                 else if (m_objectType.Equals("PdxType"))
-                 {
-                     tmpValue = (TVal)(object)new PdxType();
-                 }
-                 /*else if (m_objectType.Equals("PdxInstanceFactory"))
-                 {
-
-                     tmpValue = createIpdxInstance();
-                 }*/
-                 else if (m_objectType.Equals("AutoSerilizer"))
-                 {
-                     tmpValue = (TVal)(object)new SerializePdx1(true);
-                 }
-             }
-             else
-                 tmpValue = (TVal)(object)value;
-             return tmpValue;
-
-         }
-        private void checkContainsValueForKey(TKey key, bool expected, string logStr) {
-           //RegionPtr regionPtr = getRegion();
-           bool containsValue = m_region.ContainsValueForKey(key);
-           if (containsValue != expected)
-               FwkTest<TKey, TVal>.CurrentTest.FwkException("DoOpsTask::checkContainsValueForKey: Expected containsValueForKey(" + key + ") to be " + expected +
-                        ", but it was " + containsValue + ": " + logStr);
-        }
-        bool addNewKey()
-        {
-            int numNewKeysCreated = (int)Util.BBGet("ImageBB","NUM_NEW_KEYS_CREATED");
-	        Util.BBIncrement("ImageBB","NUM_NEW_KEYS_CREATED");
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("NumNewKeys");
-            int numNewKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("NumNewKeys");
-            if (numNewKeysCreated > numNewKeys) {
-	              FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All new keys created; returning from addNewKey");
-	              return true;
-	        }
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("entryCount");
-            int entryCount = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("entryCount");
-	        entryCount = ( entryCount < 1 ) ? 10000 : entryCount;
-            TKey key = (TKey)(object)(entryCount + numNewKeysCreated);
-	        checkContainsValueForKey(key, false, "before addNewKey");
-            TVal value = GetValue((entryCount + numNewKeysCreated));
-            m_region.Add(key,value);
-
-	        return (numNewKeysCreated >= numNewKeys);
-        }
-        bool putAllNewKey()
-        {
-            int numNewKeysCreated = (int)Util.BBGet("ImageBB","NUM_NEW_KEYS_CREATED");
-	        Util.BBIncrement("ImageBB","NUM_NEW_KEYS_CREATED");
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("NumNewKeys");
-	        int numNewKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue( "NumNewKeys" );
-                if (numNewKeysCreated > numNewKeys) {
-		              FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All new keys created; returning from putAllNewKey");
-		              return true;
-		        }
-                FwkTest<TKey, TVal>.CurrentTest.ResetKey("entryCount");
-                int entryCount = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("entryCount");
-		        entryCount = ( entryCount < 1 ) ? 10000 : entryCount;
-		        TKey key = (TKey)(object)(entryCount + numNewKeysCreated);
-                checkContainsValueForKey(key, false, "before addNewKey");
-                TVal value = GetValue((entryCount + numNewKeysCreated));
-                IDictionary<TKey, TVal> map = new Dictionary<TKey, TVal>();
-                map.Clear();
-                map.Add(key, value);
-                
-                m_region.PutAll(map);
-                return (numNewKeysCreated >= numNewKeys);
-        }
-        bool invalidate()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_INVALIDATE");
-            Util.BBIncrement("ImageBB","LASTKEY_INVALIDATE");
-	        int firstKey = (int)Util.BBGet("ImageBB", "First_Invalidate");
-	        int lastKey = (int)Util.BBGet("ImageBB", "Last_Invalidate");
-	        if(!((nextKey >= firstKey) && (nextKey <= lastKey))) {
-		        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All existing keys invalidated; returning from invalidate");
-	           return true;
-	        }
-            TKey key = (TKey)(object)(nextKey);
-	        
-	        try {
-                m_region.Invalidate(key);
-	        } catch (EntryNotFoundException e) {
-                throw new EntryNotFoundException(e.Message);
-	        }
-	        return (nextKey >= lastKey);
-        }
-        bool destroy()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_DESTROY");
-	        Util.BBIncrement("ImageBB","LASTKEY_DESTROY");
-	        int firstKey = (int)Util.BBGet("ImageBB", "First_Destroy");
-	        int lastKey = (int)Util.BBGet("ImageBB", "Last_Destroy");
-	        if(!((nextKey >= firstKey) && (nextKey <= lastKey))) {
-		        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All destroys completed; returning from destroy");
-	           return true;
-	        }
-            TKey key = (TKey)(object)(nextKey);
-	        try{
-                m_region.Remove(key);
-            } catch (CacheWriterException e) {
-              throw new CacheWriterException(e.Message);
-            } catch (EntryNotFoundException e) {
-              throw new EntryNotFoundException(e.Message);
-            }
-	        return (nextKey >= lastKey);
-        }
-        bool updateExistingKey()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_UPDATE_EXISTING_KEY");
-	        Util.BBIncrement("ImageBB","LASTKEY_UPDATE_EXISTING_KEY");
-	        int firstKey = (int)Util.BBGet("ImageBB", "First_UpdateExistingKey");
-	        int lastKey = (int)Util.BBGet("ImageBB", "Last_UpdateExistingKey");
-	        if(!((nextKey >= firstKey) && (nextKey <= lastKey))) {
-		        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All existing keys updated; returning from updateExistingKey");
-	           return true;
-	        }
-            TKey key = (TKey)(object)(nextKey);
-	        TVal existingValue = m_region[key];
-	              if (existingValue == null)
-	    	          throw new Exception("Get of key "+ key + " returned unexpected null");
-                  if (existingValue.GetType() == typeof(string))
-	    	          throw new Exception("Trying to update a key which was already updated: " + existingValue);
-                  TVal newValue = GetValue(("updated_" + nextKey));
-
-            m_region[key] = newValue;
-	        return (nextKey >= lastKey);
-        }
-        bool get()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_GET");
-	        Util.BBIncrement("ImageBB","LASTKEY_GET");
-	        int firstKey = (int)Util.BBGet("ImageBB", "First_Get");
-	        int lastKey = (int)Util.BBGet("ImageBB", "Last_Get");
-	        if(!((nextKey >= firstKey) && (nextKey <= lastKey))) {
-		        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All gets completed; returning from get");
-	           return true;
-	        }
-            TKey key = (TKey)(object)(nextKey);
-            TVal existingValue = m_region[key];
-	        if (existingValue == null)
-                FwkTest<TKey, TVal>.CurrentTest.FwkSevere("Get of key " + key + " returned unexpected " + existingValue);
-	        return (nextKey >= lastKey);
-        }
-        bool localInvalidate()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_LOCAL_INVALIDATE");
-	        Util.BBIncrement("ImageBB","LASTKEY_LOCAL_INVALIDATE");
-	        int firstKey = (int)Util.BBGet("ImageBB", "First_LocalInvalidate");
-	        int lastKey = (int)Util.BBGet("ImageBB", "Last_LocalInvalidate");
-	        if(!((nextKey >= firstKey) && (nextKey <= lastKey))) {
-		        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All local invalidates completed; returning from localInvalidate");
-	           return true;
-	        }
-            TKey key = (TKey)(object)(nextKey);
-	        try {
-                m_region.GetLocalView().Invalidate(key);
-	        } catch (EntryNotFoundException e) {
-	              throw new EntryNotFoundException(e.Message);
-	        }
-
-	        return (nextKey >= lastKey);
-        }
-        bool localDestroy()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_LOCAL_DESTROY");
-            Util.BBIncrement("ImageBB","LASTKEY_LOCAL_DESTROY");
-	        int firstKey = (int)Util.BBGet("ImageBB", "First_LocalDestroy");
-	        int lastKey = (int)Util.BBGet("ImageBB", "Last_LocalDestroy");
-	        if(!((nextKey >= firstKey) && (nextKey <= lastKey))) {
-		        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All local destroys completed; returning from localDestroy");
-	           return true;
-	        }
-            TKey key = (TKey)(object)(nextKey);
-	        try {
-                m_region.GetLocalView().Remove(key);
-            } catch (EntryNotFoundException e) {
-	          throw new EntryNotFoundException(e.Message);
-            }
-	        return (nextKey >= lastKey);
-        }
-
-        
-    }
-
-  //------------------------------------DoOpsTask end --------------------------
-
-  //------------------------------ ExpectedRegionContents Start----------------
-    public class ExpectedRegionContents
-    {
-
-        // instance fields
-        // KeyIntevals.NONE
-        private bool m_containsKey_none;            // expected value of m_containsKey for KeyIntervals.NONE
-        private bool m_containsValue_none;          // expected value of m_containsValue for KeyIntervals.NONE
-        private bool m_getAllowed_none;             // if true, then check the value with a get
-
-        // KeyIntevals.INVALIDATE
-        private bool m_containsKey_invalidate;
-        private bool m_containsValue_invalidate;
-        private bool m_getAllowed_invalidate;
-
-        // KeyIntevals.LOCAL_INVALIDATE
-        private bool m_containsKey_localInvalidate;
-        private bool m_containsValue_localInvalidate;
-        private bool m_getAllowed_localInvalidate;
-
-        // KeyIntevals.DESTROY
-        private bool m_containsKey_destroy;
-        private bool m_containsValue_destroy;
-        private bool m_getAllowed_destroy;
-
-        // KeyIntevals.LOCAL_DESTROY
-        private bool m_containsKey_localDestroy;
-        private bool m_containsValue_localDestroy;
-        private bool m_getAllowed_localDestroy;
-
-        // KeyIntevals.UPDATE
-        private bool m_containsKey_update;
-        private bool m_containsValue_update;
-        private bool m_getAllowed_update;
-        private bool m_valueIsUpdated;
-
-        // KeyIntervals.GET
-        private bool m_containsKey_get;
-        private bool m_containsValue_get;
-        private bool m_getAllowed_get;
-
-        // new keys
-        private bool m_containsKey_newKey;
-        private bool m_containsValue_newKey;
-        private bool m_getAllowed_newKey;
-
-        // region size specifications
-        int m_exactSize;
-        int m_minSize;
-        int m_maxSize;
-
-        // constructors
-        public ExpectedRegionContents(bool m_containsKey, bool m_containsValue, bool m_getAllowed)
-        {
-            m_containsKey_none = m_containsKey;
-            m_containsKey_invalidate = m_containsKey;
-            m_containsKey_localInvalidate = m_containsKey;
-            m_containsKey_destroy = m_containsKey;
-            m_containsKey_localDestroy = m_containsKey;
-            m_containsKey_update = m_containsKey;
-            m_containsKey_get = m_containsKey;
-            m_containsKey_newKey = m_containsKey;
-
-            m_containsValue_none = m_containsValue;
-            m_containsValue_invalidate = m_containsValue;
-            m_containsValue_localInvalidate = m_containsValue;
-            m_containsValue_destroy = m_containsValue;
-            m_containsValue_localDestroy = m_containsValue;
-            m_containsValue_update = m_containsValue;
-            m_containsValue_get = m_containsValue;
-            m_containsValue_newKey = m_containsValue;
-
-            m_getAllowed_none = m_getAllowed;
-            m_getAllowed_invalidate = m_getAllowed;
-            m_getAllowed_localInvalidate = m_getAllowed;
-            m_getAllowed_destroy = m_getAllowed;
-            m_getAllowed_localDestroy = m_getAllowed;
-            m_getAllowed_update = m_getAllowed;
-            m_getAllowed_get = m_getAllowed;
-            m_getAllowed_newKey = m_getAllowed;
-            m_valueIsUpdated = false;
-
-        }
-
-        public ExpectedRegionContents(bool m_containsKeyNone, bool m_containsValueNone,
-                                     bool m_containsKeyInvalidate, bool m_containsValueInvalidate,
-                                     bool m_containsKeyLocalInvalidate, bool m_containsValueLocalInvalidate,
-                                     bool m_containsKeyDestroy, bool m_containsValueDestroy,
-                                     bool m_containsKeyLocalDestroy, bool m_containsValueLocalDestroy,
-                                     bool m_containsKeyUpdate, bool m_containsValueUpdate,
-                                     bool m_containsKeyGet, bool m_containsValueGet,
-                                     bool m_containsKeyNewKey, bool m_containsValueNewKey,
-                                     bool m_getAllowed,
-                                     bool updated)
-        {
-            m_containsKey_none = m_containsKeyNone;
-            m_containsValue_none = m_containsValueNone;
-
-            m_containsKey_invalidate = m_containsKeyInvalidate;
-            m_containsValue_invalidate = m_containsValueInvalidate;
-
-            m_containsKey_localInvalidate = m_containsKeyLocalInvalidate;
-            m_containsValue_localInvalidate = m_containsValueLocalInvalidate;
-
-            m_containsKey_destroy = m_containsKeyDestroy;
-            m_containsValue_destroy = m_containsValueDestroy;
-
-            m_containsKey_localDestroy = m_containsKeyLocalDestroy;
-            m_containsValue_localDestroy = m_containsValueLocalDestroy;
-
-            m_containsKey_update = m_containsKeyUpdate;
-            m_containsValue_update = m_containsValueUpdate;
-
-            m_containsKey_get = m_containsKeyGet;
-            m_containsValue_get = m_containsValueGet;
-
-            m_containsKey_newKey = m_containsKeyNewKey;
-            m_containsValue_newKey = m_containsValueNewKey;
-
-            m_getAllowed_none = m_getAllowed;
-            m_getAllowed_invalidate = m_getAllowed;
-            m_getAllowed_localInvalidate = m_getAllowed;
-            m_getAllowed_destroy = m_getAllowed;
-            m_getAllowed_localDestroy = m_getAllowed;
-            m_getAllowed_update = m_getAllowed;
-            m_getAllowed_get = m_getAllowed;
-            m_getAllowed_newKey = m_getAllowed;
-            m_valueIsUpdated = updated;
-        }
-
-        //================================================================================
-        // getter methods
-        public bool containsKey_none()
-        {
-            return m_containsKey_none;
-        }
-        public bool containsValue_none()
-        {
-            return m_containsValue_none;
-        }
-        public bool getAllowed_none()
-        {
-            return m_getAllowed_none;
-        }
-        public bool containsKey_invalidate()
-        {
-            return m_containsKey_invalidate;
-        }
-        public bool containsValue_invalidate()
-        {
-            return m_containsValue_invalidate;
-        }
-        public bool getAllowed_invalidate()
-        {
-            return m_getAllowed_invalidate;
-        }
-        public bool containsKey_localInvalidate()
-        {
-            return m_containsKey_localInvalidate;
-        }
-        public bool containsValue_localInvalidate()
-        {
-            return m_containsValue_localInvalidate;
-        }
-        public bool getAllowed_localInvalidate()
-        {
-            return m_getAllowed_localInvalidate;
-        }
-        public bool containsKey_destroy()
-        {
-            return m_containsKey_destroy;
-        }
-        public bool containsValue_destroy()
-        {
-            return m_containsValue_destroy;
-        }
-        public bool getAllowed_destroy()
-        {
-            return m_getAllowed_destroy;
-        }
-        public bool containsKey_localDestroy()
-        {
-            return m_containsKey_localDestroy;
-        }
-        public bool containsValue_localDestroy()
-        {
-            return m_containsValue_localDestroy;
-        }
-        public bool getAllowed_localDestroy()
-        {
-            return m_getAllowed_localDestroy;
-        }
-        public bool containsKey_update()
-        {
-            return m_containsKey_update;
-        }
-        public bool containsValue_update()
-        {
-            return m_containsValue_update;
-        }
-        public bool getAllowed_update()
-        {
-            return m_getAllowed_update;
-        }
-        public bool valueIsUpdated()
-        {
-            return m_valueIsUpdated;
-        }
-        public bool containsKey_get()
-        {
-            return m_containsKey_get;
-        }
-        public bool containsValue_get()
-        {
-            return m_containsValue_get;
-        }
-        public bool getAllowed_get()
-        {
-            return m_getAllowed_get;
-        }
-        public bool containsKey_newKey()
-        {
-            return m_containsKey_newKey;
-        }
-        public bool containsValue_newKey()
-        {
-            return m_containsValue_newKey;
-        }
-        public bool getAllowed_newKey()
-        {
-            return m_getAllowed_newKey;
-        }
-        public int exactSize()
-        {
-            return m_exactSize;
-        }
-        public int minSize()
-        {
-            return m_minSize;
-        }
-        public int maxSize()
-        {
-            return m_maxSize;
-        }
-
-        //================================================================================
-        // setter methods
-
-        public void containsKey_none(bool abool)
-        {
-            m_containsKey_none = abool;
-        }
-
-        public void containsValue_none(bool abool)
-        {
-            m_containsValue_none = abool;
-        }
-
-        public void containsKey_invalidate(bool abool)
-        {
-            m_containsKey_invalidate = abool;
-        }
-
-        public void containsValue_invalidate(bool abool)
-        {
-            m_containsValue_invalidate = abool;
-        }
-
-        public void containsKey_localInvalidate(bool abool)
-        {
-            m_containsKey_localInvalidate = abool;
-        }
-
-        public void containsValue_localInvalidate(bool abool)
-        {
-            m_containsValue_localInvalidate = abool;
-        }
-
-        public void containsKey_destroy(bool abool)
-        {
-            m_containsKey_destroy = abool;
-        }
-
-        public void containsValue_destroy(bool abool)
-        {
-            m_containsValue_destroy = abool;
-        }
-
-        public void containsKey_localDestroy(bool abool)
-        {
-            m_containsKey_localDestroy = abool;
-        }
-
-        public void containsValue_localDestroy(bool abool)
-        {
-            m_containsValue_localDestroy = abool;
-        }
-
-        public void containsKey_update(bool abool)
-        {
-            m_containsKey_update = abool;
-        }
-
-        public void containsValue_update(bool abool)
-        {
-            m_containsValue_update = abool;
-        }
-
-        public void containsKey_get(bool abool)
-        {
-            m_containsKey_get = abool;
-        }
-
-        public void containsValue_get(bool abool)
-        {
-            m_containsValue_get = abool;
-        }
-
-        public void containsKey_newKey(bool abool)
-        {
-            m_containsKey_newKey = abool;
-        }
-
-        public void containsValue_newKey(bool abool)
-        {
-            m_containsValue_newKey = abool;
-        }
-
-        public void exactSize(int anInt)
-        {
-            m_exactSize = anInt;
-        }
-
-        public void minSize(int anInt)
-        {
-            m_minSize = anInt;
-        }
-
-        public void maxSize(int anInt)
-        {
-            m_maxSize = anInt;
-        }
-        public void valueIsUpdated(bool abool)
-        {
-            m_valueIsUpdated = abool;
-        }
-
-        public string toString() {
-            StringBuilder attrsSB = new StringBuilder();
-            attrsSB.Append(Environment.NewLine + "m_containsKey_none: " + m_containsKey_none);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_none: " + m_containsValue_none);
-            attrsSB.Append(Environment.NewLine + "m_containsKey_invalidate: " + m_containsKey_invalidate);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_invalidate: " + m_containsValue_invalidate);
-            attrsSB.Append(Environment.NewLine + "m_containsKey_localInvalidate: " + m_containsKey_localInvalidate);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_localInvalidate: " + m_containsValue_localInvalidate);
-            attrsSB.Append(Environment.NewLine + "m_containsKey_destroy: " + m_containsKey_destroy);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_destroy: " + m_containsValue_destroy);
-            attrsSB.Append(Environment.NewLine + "m_containsKey_localDestroy: " + m_containsKey_localDestroy);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_localDestroy: " + m_containsValue_localDestroy);
-            attrsSB.Append(Environment.NewLine + "m_containsKey_update: " + m_containsKey_update);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_update: " + m_containsValue_update);
-            attrsSB.Append(Environment.NewLine + "m_containsKey_get: " + m_containsKey_get);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_get: " + m_containsValue_get);
-            attrsSB.Append(Environment.NewLine + "m_containsKey_newKey: " + m_containsKey_newKey);
-            attrsSB.Append(Environment.NewLine + "m_containsValue_newKey: " + m_containsValue_newKey);
-            attrsSB.Append(Environment.NewLine );
-            return attrsSB.ToString();
-
-        }
-    }
-
-//================================================================================
-  public class CacheServer<TKey, TVal> : FwkTest<TKey, TVal>
-  {
-    #region Private constants and statics
-
-    private static TimeSpan QueryResponseTimeout = TimeSpan.FromSeconds(600);
-    private const string RegionName = "regionName";
-    private const string ValueSizes = "valueSizes";
-    private const string OpsSecond = "opsSecond";
-    private const string EntryCount = "entryCount";
-    private const string WorkTime = "workTime";
-    private const string EntryOps = "entryOps";
-    private const string LargeSetQuery = "largeSetQuery";
-    private const string UnsupportedPRQuery = "unsupportedPRQuery";
-    private const string ObjectType = "objectType";
-    private const int NUM_EXTRA_KEYS = 100;
-    
-   // private const bool MultiRegion = "multiRegion";
-
-    private static Dictionary<string, int> OperationsMap =
-      new Dictionary<string, int>();
-    private static Dictionary<string, int> ExceptionsMap =
-      new Dictionary<string, int>();
-    private static bool m_istransaction = false;
-    private static bool isSerialExecution = false;
-    protected static bool isEmptyClient = false;  // true if this is a bridge client with empty dataPolicy
-    protected static bool isThinClient = false; // true if this is a bridge client with eviction to keep it small
-    private static Dictionary<TKey, TVal> regionSnapshot = null;
-    //  new Dictionary<TKey, TVal>();
-    private static List<TKey> destroyedKeys = null;// = new List<TKey>();
-    //private static List<TKey> destroyList = null;
-    private int keyCount;
-    private static List<TKey> m_KeysA = new List<TKey>();
-    private static ExpectedRegionContents[] expectedRgnContents = new ExpectedRegionContents[5];
-    private static int totalNumKeys = 0;
-    //Assembly m_pdxVersionOneAsm;
-    //Assembly m_pdxVersionTwoAsm;
-    //protected TKey[] m_KeysA;
-    #endregion
-      /*
-       Util.BBSet("OpsBB","CREATES",creates);
-      Util.BBSet("OpsBB","UPDATES",puts);
-      Util.BBSet("OpsBB","DESTROYS",dests);
-      Util.BBSet("OpsBB","GETS",gets);
-      Util.BBSet("OpsBB","INVALIDATES",invals);
-       
-       
-       */
-      public const string OPSBB="OpsBB";
-      public const string CREATE = "CREATE";
-      public const string UPDATES = "UPDATES";
-      public const string DESTROYS = "DESTROYS";
-      public const string GETS = "GETS";
-      public const string INVALIDATES = "INVALIDATES";
-      
-    #region Private utility methods
-
-    private IRegion<TKey, TVal> GetRegion()
-    {
-      return GetRegion(null);
-    }
-
-    protected IRegion<TKey, TVal> GetRegion(string regionName)
-    {
-      IRegion<TKey, TVal> region;
-      if (regionName == null)
-      {
-        regionName = GetStringValue("regionName");
-      }
-      if (regionName == null)
-      {
-        region = (IRegion<TKey, TVal>)GetRootRegion();
-        if (region == null)
-        {
-          IRegion<TKey, TVal>[] rootRegions = CacheHelper<TKey, TVal>.DCache.RootRegions<TKey, TVal>();
-          if (rootRegions != null && rootRegions.Length > 0)
-          {
-            region = rootRegions[Util.Rand(rootRegions.Length)];
-          }
-        }
-      }
-      else
-      {
-        region = CacheHelper<TKey, TVal>.GetRegion(regionName);
-      }
-      return region;
-    }
-
-    private void AddValue(IRegion<TKey, TVal> region, int count, byte[] valBuf)
-    {
-      if (region == null)
-      {
-        FwkSevere("CacheServer::AddValue(): No region to perform add on.");
-        return;
-      }
-      TKey key = (TKey)(object)count.ToString();
-      TVal value = (TVal)(object)valBuf;
-      BitConverter.GetBytes(count).CopyTo(valBuf, 0);
-      BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-      try
-      {
-        region.Add(key, value);
-        //FwkInfo("key: {0}  value: {1}", key, Encoding.ASCII.GetString(value.Value));
-      }
-      catch (Exception ex)
-      {
-        FwkException("CacheServer.AddValue() caught Exception: {0}", ex);
-      }
-    }
-
-    private TKey GetKey(int max)
-    {
-      ResetKey(ObjectType);
-      string objectType = GetStringValue(ObjectType);
-      QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-      int numSet = 0;
-      int setSize = 0;
-      if (objectType != null && (objectType == "Portfolio" || objectType == "PortfolioPdx"))
-      {
-        setSize = qh.PortfolioSetSize;
-        numSet = max / setSize;
-        return (TKey)(object)String.Format("port{0}-{1}", Util.Rand(numSet), Util.Rand(setSize));
-      }
-      else if (objectType != null && (objectType == "Position" || objectType == "PositionPdx"))
-      {
-        setSize = qh.PositionSetSize;
-        numSet = max / setSize;
-        return (TKey)(object)String.Format("pos{0}-{1}", Util.Rand(numSet), Util.Rand(setSize));
-      }
-      return (TKey)(object)Util.Rand(max).ToString();
-    }
-
-    private TVal GetUserObject(string objType)
-    {
-      TVal usrObj = default(TVal);
-      ResetKey(EntryCount);
-      int numOfKeys = GetUIntValue(EntryCount);
-      ResetKey(ValueSizes);
-      int objSize = GetUIntValue(ValueSizes);
-      QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-      int numSet = 0;
-      int setSize = 0;
-      if (objType != null && objType == "Portfolio")
-      {
-        setSize = qh.PortfolioSetSize;
-        numSet = numOfKeys / setSize;
-        usrObj = (TVal)(object) new Portfolio(Util.Rand(setSize), objSize);
-      }
-      else if (objType != null && objType == "Position")
-      {
-        setSize = qh.PositionSetSize;
-        numSet = numOfKeys / setSize;
-        int numSecIds = Portfolio.SecIds.Length;
-        usrObj = (TVal)(object)new Position(Portfolio.SecIds[setSize % numSecIds], setSize * 100);
-      }
-      if (objType != null && objType == "PortfolioPdx")
-      {
-        setSize = qh.PortfolioSetSize;
-        numSet = numOfKeys / setSize;
-        usrObj = (TVal)(object)new PortfolioPdx(Util.Rand(setSize), objSize);
-      }
-      else if (objType != null && objType == "PositionPdx")
-      {
-        setSize = qh.PositionSetSize;
-        numSet = numOfKeys / setSize;
-        int numSecIds = PortfolioPdx.SecIds.Length;
-        usrObj = (TVal)(object)new PositionPdx(PortfolioPdx.SecIds[setSize % numSecIds], setSize * 100);
-      }
-      return usrObj;
-    }
-
-    private bool AllowQuery(QueryCategory category, bool haveLargeResultset,
-      bool islargeSetQuery, bool isUnsupportedPRQuery)
-    {
-      if (category == QueryCategory.Unsupported)
-      {
-        return false;
-      }
-      else if (haveLargeResultset != islargeSetQuery)
-      {
-        return false;
-      }
-      else if (isUnsupportedPRQuery &&
-               ((category == QueryCategory.MultiRegion) ||
-                (category == QueryCategory.NestedQueries)))
-      {
-        return false;
-      }
-      else
-      {
-        return true;
-      }
-    }
-    private void remoteQuery(QueryStrings currentQuery, bool isLargeSetQuery, 
-      bool isUnsupportedPRQuery, int queryIndex,bool isparam,bool isStructSet)
-    {
-      DateTime startTime;
-      DateTime endTime;
-      TimeSpan elapsedTime;
-      var qs = CheckQueryService();
-      if (AllowQuery(currentQuery.Category, currentQuery.IsLargeResultset,
-            isLargeSetQuery, isUnsupportedPRQuery))
-        {
-          string query = currentQuery.Query;
-          FwkInfo("CacheServer.RunQuery: ResultSet Query Category [{0}], " +
-            "String [{1}].", currentQuery.Category, query);
-          Query<object> qry = qs.NewQuery<object>(query);
-          object[] paramList = null;
-          if (isparam)
-          {
-            Int32 numVal = 0;
-            if (isStructSet)
-            {
-              paramList = new object[QueryStatics.NoOfQueryParamSS[queryIndex]];
-
-              for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParamSS[queryIndex]; ind++)
-              {
-                try
-                {
-                  numVal = Convert.ToInt32(QueryStatics.QueryParamSetSS[queryIndex][ind]);
-                  paramList[ind] = numVal;
-                }
-                catch (FormatException)
-                {
-                  paramList[ind] = (System.String)QueryStatics.QueryParamSetSS[queryIndex][ind];
-                }
-              }
-            }
-            else
-            {
-              paramList = new object[QueryStatics.NoOfQueryParam[queryIndex]];
-              for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParam[queryIndex]; ind++)
-              {
-                try
-                {
-                  numVal = Convert.ToInt32(QueryStatics.QueryParamSet[queryIndex][ind]);
-                  paramList[ind] = numVal;
-                }
-                catch (FormatException)
-                {
-                  paramList[ind] = (System.String)QueryStatics.QueryParamSet[queryIndex][ind];
-                }
-              }
-            }
-          }
-          ISelectResults<object> results = null;
-          startTime = DateTime.Now;
-          if (isparam)
-          {
-            results = qry.Execute(paramList, TimeSpan.FromSeconds(600));
-          }
-          else
-          {
-            results = qry.Execute(TimeSpan.FromSeconds(600));
-          }
-          endTime = DateTime.Now;
-          elapsedTime = endTime - startTime;
-          FwkInfo("CacheServer.RunQuery: Time Taken to execute" +
-            " the query [{0}]: {1}ms", query, elapsedTime.TotalMilliseconds);
-        }
-    }
-
-    private void RunQuery()
-    {
-      FwkInfo("In CacheServer.RunQuery");
-
-      try
-      {
-        ResetKey(EntryCount);
-        int numOfKeys = GetUIntValue(EntryCount);
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        int setSize = qh.PortfolioSetSize;
-        if (numOfKeys < setSize)
-        {
-          setSize = numOfKeys;
-        }
-        int i = Util.Rand(QueryStrings.RSsize);
-        ResetKey(LargeSetQuery);
-        ResetKey(UnsupportedPRQuery);
-        bool isLargeSetQuery = GetBoolValue(LargeSetQuery);
-        bool isUnsupportedPRQuery = GetBoolValue(UnsupportedPRQuery);
-        QueryStrings currentQuery = QueryStatics.ResultSetQueries[i];
-        remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i,false,false);
-        i = Util.Rand(QueryStrings.SSsize);
-        int[] a = new int[] { 4, 6, 7, 9, 12, 14, 15, 16 };
-        if ((typeof(TVal).Equals(typeof(Apache.Geode.Client.Tests.PortfolioPdx)) ||
-          (typeof(TVal).Equals(typeof(Apache.Geode.Client.Tests.PositionPdx)))) && ((IList<int>)a).Contains(i))
-        {
-          FwkInfo("Skiping Query for pdx object [{0}]", QueryStatics.StructSetQueries[i]);
-        }
-        else
-        {
-          currentQuery = QueryStatics.StructSetQueries[i];
-          remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i, false, false);
-        }
-        i = Util.Rand(QueryStrings.RSPsize);
-        currentQuery = QueryStatics.ResultSetParamQueries[i];
-        remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i,true,false);
-        i = Util.Rand(QueryStrings.SSPsize);
-        if ((typeof(TVal).Equals(typeof(Apache.Geode.Client.Tests.PortfolioPdx)) ||
-          (typeof(TVal).Equals(typeof(Apache.Geode.Client.Tests.PositionPdx)))) && ((IList<int>)a).Contains(i))
-        {
-          FwkInfo("Skiping Query for pdx object [{0}]", QueryStatics.StructSetParamQueries[i]);
-        }
-        else
-        {
-          currentQuery = QueryStatics.StructSetParamQueries[i];
-          remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i, true, true);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("CacheServer.RunQuery: Caught Exception: {0}", ex);
-      }
-      FwkInfo("CacheServer.RunQuery complete.");
-    }
-
-    private void UpdateOperationsMap(string opCode, int numOps)
-    {
-      UpdateOpsMap(OperationsMap, opCode, numOps);
-    }
-
-    private void UpdateExceptionsMap(string opCode, int numOps)
-    {
-      UpdateOpsMap(ExceptionsMap, opCode, numOps);
-    }
-
-    private void UpdateOpsMap(Dictionary<string, int> map, string opCode,
-      int numOps)
-    {
-      lock (((ICollection)map).SyncRoot)
-      {
-        int currentOps;
-        if (!map.TryGetValue(opCode, out currentOps))
-        {
-          currentOps = 0;
-        }
-        map[opCode] = currentOps + numOps;
-      }
-    }
-
-    private int GetOpsFromMap(Dictionary<string, int> map, string opCode)
-    {
-      int numOps;
-      lock (((ICollection)map).SyncRoot)
-      {
-        if (!map.TryGetValue(opCode, out numOps))
-        {
-          numOps = 0;
-        }
-      }
-      return numOps;
-    }
-    private void PutAllOps()
-    {
-      IRegion<TKey,TVal> region = GetRegion();
-      IDictionary<TKey, TVal> map = new Dictionary<TKey,TVal>();
-      int valSize = GetUIntValue(ValueSizes);
-      int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-      valSize = ((valSize < minValSize) ? minValSize : valSize);
-      string valBuf = null;
-      ResetKey(ObjectType);
-      string objectType = GetStringValue(ObjectType);
-      if (objectType != null)
-      {
-        Int32 numSet = 0;
-        Int32 setSize = 0;
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        TVal port;
-        setSize = qh.PortfolioSetSize;
-        numSet = 200 / setSize;
-        for (int set = 1; set <= numSet; set++)
-        {
-          for (int current = 1; current <= setSize; current++)
-          {
-            if (objectType != "PortfolioPdx")
-            {
-              port = (TVal)(object)new Portfolio(current, valSize);
-            }
-            else
-            {
-              port = (TVal)(object)new PortfolioPdx(current, valSize);
-            }
-            string Id = String.Format("port{0}-{1}", set,current); 
-            TKey key = (TKey)(object)Id.ToString();
-            map.Add(key, port);
-          }
-        }
-      }
-      else
-      {
-        valBuf = new string('A', valSize);
-        for (int count = 0; count < 200; count++)
-        {
-          TKey key = (TKey)(object)count.ToString();
-          TVal value = (TVal)(object)Encoding.ASCII.GetBytes(valBuf);
-          map.Add(key, value);
-        }
-      }
-      region.PutAll(map, TimeSpan.FromSeconds(60));
-    }
-
-    private void GetAllOps()
-    {
-      IRegion<TKey, TVal> region = GetRegion();
-      List<TKey> keys  = new List<TKey>();
-      keys.Clear();
-      for (int count = 0; count < 200; count++)
-      {
-        TKey key = (TKey)(object)count.ToString();
-        keys.Add(key);
-      }    
-      IDictionary<TKey, TVal> values = new Dictionary<TKey, TVal>();
-      values.Clear();
-      region.GetAll(keys.ToArray(), values, null, false);
-    }
-    #endregion
-
-    #region Public methods
-    public static ICacheListener<TKey, TVal> CreateSilenceListener()
-    {
-      return new SilenceListener<TKey, TVal>();
-    }
-    public virtual void DoCreatePool()
-    {
-      FwkInfo("In DoCreatePool()");
-      try
-      {
-        CreatePool();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreatePool() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreatePool() complete.");
-    }
-   
-    public virtual void DoCreateRegion()
-    {
-      FwkInfo("In DoCreateRegion()");
-      try {
-        IRegion<TKey, TVal> region = CreateRootRegion();
-        ResetKey("useTransactions");
-        m_istransaction = GetBoolValue("useTransactions");
-        isEmptyClient = !(region.Attributes.CachingEnabled);
-        isThinClient = region.Attributes.CachingEnabled;
-        if (region == null) {
-          FwkException("DoCreateRegion()  could not create region.");
-        }
-        
-        FwkInfo("DoCreateRegion()  Created region '{0}'", region.Name);
-      } catch (Exception ex) {
-        FwkException("DoCreateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreateRegion() complete.");
-    }
-
-    public void DoCloseCache()
-    {
-      FwkInfo("DoCloseCache()  Closing cache and disconnecting from" +
-        " distributed system.");
-      CacheHelper<TKey, TVal>.Close();
-    }
-    public void DoRegisterAllKeys()
-    {
-      FwkInfo("In DoRegisterAllKeys()");
-      try
-      {
-          IRegion<TKey, TVal> region = GetRegion();
-          FwkInfo("DoRegisterAllKeys() region name is {0}", region.Name);
-          bool isDurable = GetBoolValue("isDurableReg");
-          ResetKey("getInitialValues");
-          bool isGetInitialValues = GetBoolValue("getInitialValues");
-          bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-          bool isReceiveValues = true;
-          if (checkReceiveVal)
-          {
-              ResetKey("receiveValue");
-              isReceiveValues = GetBoolValue("receiveValue");
-          }
-          ResetKey("sleepBeforeRegisterInterest");
-          int sleepTime = GetUIntValue("sleepBeforeRegisterInterest");
-          sleepTime = sleepTime > 0 ? sleepTime : 0;
-          FwkInfo("Sleeping for " + sleepTime + " millis");
-          Thread.Sleep(sleepTime);
-          region.GetSubscriptionService().RegisterAllKeys(isDurable, isGetInitialValues, isReceiveValues);
-          String durableClientId = CacheHelper<TKey, TVal>.DCache.SystemProperties.DurableClientId;
-          if (durableClientId.Length > 0)
-          {
-              CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-          }
-      }
-      catch (Exception ex)
-      {
-          FwkException("DoRegisterAllKeys() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRegisterAllKeys() complete.");
-    }
-    public void DoFeed()
-    {
-      FwkInfo("CacheServer.DoFeed() called.");
-
-      int opsSec = GetUIntValue(OpsSecond);
-      opsSec = (opsSec < 1) ? 0 : opsSec;
-
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int cnt = 0;
-      int valSize = GetUIntValue(ValueSizes);
-      int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-      valSize = ((valSize < minValSize) ? minValSize : valSize);
-      string valBuf = new string('A', valSize);
-
-      IRegion<TKey,TVal> region = GetRegion();
-      PaceMeter pm = new PaceMeter(opsSec);
-      while (cnt++ < entryCount)
-      {
-        AddValue(region, cnt, Encoding.ASCII.GetBytes(valBuf));
-        pm.CheckPace();
-      }
-    }
-    protected void removeDuplicates(List<TKey> destroyedKeys)
-    {
-      List<TKey> myStringList = new List<TKey>();
-      foreach (TKey s in destroyedKeys)
-      {
-        if (!myStringList.Contains(s))
-        {
-          myStringList.Add(s);
-        }
-      }
-      destroyedKeys = myStringList;
-      //return myStringList;
-    }
-    // Tx code start
-   
-    protected void verifyContainsKey(IRegion<TKey, TVal> m_region,TKey key, bool expected)
-    {
-      //bool containsKey = m_region.GetLocalView().ContainsKey(key);
-
-      bool containsKey = false;
-      if (isEmptyClient || m_istransaction)
-        containsKey = m_region.ContainsKey(key);
-      else
-        containsKey = m_region.GetLocalView().ContainsKey(key);
-      if (containsKey != expected)
-      {
-        throw new Exception("Expected ContainsKey() for " + key + " to be " + expected +
-                  " in " + m_region.FullPath + ", but it is " + containsKey);
-      }
-    }
-    
-    protected void verifyContainsValueForKey(IRegion<TKey, TVal> m_region,TKey key, bool expected)
-    {
-      
-      //bool containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-      bool containsValueForKey = false;
-      if (isEmptyClient ||m_istransaction)
-        containsValueForKey = m_region.ContainsValueForKey(key);
-      else
-        containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-      if (containsValueForKey != expected)
-      {
-        throw new Exception("Expected ContainsValueForKey() for " + key + " to be " + expected +
-                  " in " + m_region.FullPath + ", but it is " + containsValueForKey);
-      }
-       
-    }
-    protected void verifySize(IRegion<TKey, TVal> m_region,int expectedSize)
-    {
-      int size = 0;
-      if (isEmptyClient || m_istransaction)
-        size = m_region.Count;
-      else
-        size = m_region.GetLocalView().Count;
-      if (size != expectedSize)
-      {
-        if (size < 1000)
-        {
-          StringBuilder sb = new StringBuilder();
-          sb.Append("region has wrong size (").Append(size)
-            .Append(").  Dump of region follows:")
-            .Append("\n");
-          ICollection<RegionEntry<TKey, TVal>> regionentry = m_region.GetEntries(false);
-          foreach (RegionEntry<TKey, TVal> kvp in regionentry)
-         {
-           TKey key = kvp.Key;
-           TVal Value = kvp.Value;
-            sb.Append(key).Append(") -> ").Append(Value)
-               .Append("\n");
-          }
-          FwkInfo(sb.ToString());
-        }
-        throw new Exception("Expected size of " + m_region.FullPath + " to be " +
-           expectedSize + ", but it is " + size);
-      }
-      /*
-      int size = m_region.Count;
-      if (size != expectedSize)
-      {
-        throw new Exception("Expected size of " + m_region.FullPath + " to be " +
-           expectedSize + ", but it is " + size);
-      }*/
-    }
-    protected TKey GetNewKey()
-    {
-      ResetKey("distinctKeys");
-      int numKeys = GetUIntValue("distinctKeys");
-      keyCount = Util.BBIncrement("uniqueKey", "count");
-      TKey key = default(TKey);
-      if (typeof(TKey) == typeof(string))
-      {
-          String keybuf = String.Format("Key-{0}-{1}-{2}", Util.PID, Util.ThreadID, keyCount);
-          key = (TKey)(object)(keybuf);
-      }
-      else
-      {
-          key = (TKey)(object)(keyCount);
-      }
-      return key;
-    }
-    protected TKey GetExistingKey(bool useServerKeys)
-    {
-      IRegion<TKey, TVal> region = GetRegion();
-      TKey key = default(TKey);
-      //if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-      //{
-        if (useServerKeys)
-        {
-          int size = region.Count;
-          TKey[] keys = (TKey[])region.Keys;
-          key = keys[Util.Rand(0, keys.Length)];
-        }
-        else
-        {
-          int size = region.GetLocalView().Count;
-          TKey[] keys = (TKey[])region.GetLocalView().Keys;
-          key = keys[Util.Rand(0, size)];
-        }
-      /*}
-      else
-      {
-        return key;
-      }*/
-      keyCount = Util.BBIncrement("uniqueKey", "count");
-      return key;
-    }
-    protected TKey addEntry(IRegion<TKey, TVal> m_region)
-    {
-      TKey key = GetNewKey();
-      TVal value = GetValue();
-      int beforeSize = 0;
-      if (isEmptyClient || m_istransaction)
-        beforeSize = m_region.Count;
-      else
-        beforeSize = m_region.GetLocalView().Count;
-      try
-      {
-        m_region.Add(key, value);
-        
-      }
-      catch (EntryExistsException ex)
-      {
-        if (isSerialExecution)
-        {
-          // cannot get this exception; nobody else can have this key
-          throw new Exception(ex.StackTrace);
-        }
-        else
-        {
-          Util.Log("Caught {0} (expected with concurrent execution); continuing with test", ex);
-        }
-      }
-      catch (Exception ex)
-      {
-         throw new Exception(ex.Message);
-      }
-      // validation
-      if (isSerialExecution)
-      {
-        if (isEmptyClient)
-        {
-          if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-          {
-            verifySize(m_region,0);
-          }
-        }
-        else if (isThinClient)
-        { 
-          if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-          {
-            // new entry should be in the local region
-            verifyContainsKey(m_region,key, true);
-            verifyContainsValueForKey(m_region,key, true);
-          }
-        }
-        else
-        { // region has all keys/values
-          verifyContainsKey(m_region,key, true);
-          verifyContainsValueForKey(m_region,key, true);
-          verifySize(m_region,beforeSize + 1);
-        }
-        regionSnapshot[key] = value;
-        destroyedKeys.Remove(key);
-      }
-      return key;
-
-    }
-    protected void updateEntry(IRegion<TKey, TVal> r)
-    {
-      TKey key = GetExistingKey(isEmptyClient||isThinClient);
-      if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-      {
-        int size = r.Count;
-        if (isSerialExecution && (size != 0))
-          throw new Exception("getExistingKey returned " + key + ", but region size is " + size);
-        FwkInfo("updateEntry: No keys in region");
-        return;
-      }
-      int beforeSize = 0;
-      if (isEmptyClient || m_istransaction)
-        beforeSize = r.Count;
-      else
-        beforeSize = r.GetLocalView().Count;
-      TVal value = GetValue();
-      r[key] = value;
-      
-      // validation
-      // cannot validate return value from put due to bug 36436; in peer configurations
-      // we do not make any guarantees about the return value
-      if (isSerialExecution)
-      {
-        if (isEmptyClient)
-        {
-          if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-          {
-            verifySize(r, 0);
-          }
-        }
-        else if (isThinClient)
-        { // we have eviction
-          if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-          {
-            verifyContainsKey(r, key, true);
-            verifyContainsValueForKey(r, key, true);
-           
-          }
-        }
-        else
-        { // we have all keys/values
-          verifyContainsKey(r, key, true);
-          verifyContainsValueForKey(r, key, true);
-          verifySize(r, beforeSize);
-        }
-
-        // record the current state
-        regionSnapshot[key] = value;
-        destroyedKeys.Remove(key);
-      }
-    }
-    protected void invalidateEntry(IRegion<TKey, TVal> m_region,bool isLocalInvalidate)
-    {
-      int beforeSize = 0;
-      if (isEmptyClient || m_istransaction)
-        beforeSize = m_region.Count;
-      else
-        beforeSize = m_region.GetLocalView().Count;
-      TKey key = GetExistingKey(isEmptyClient||isThinClient);
-      if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-      {
-        if (isSerialExecution && (beforeSize != 0))
-          throw new Exception("getExistingKey returned " + key + ", but region size is " + beforeSize);
-        FwkInfo("invalidateEntry: No keys in region");
-      }
-      bool containsKey = m_region.GetLocalView().ContainsKey(key);
-      bool containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-      FwkInfo("containsKey for " + key + ": " + containsKey);
-      FwkInfo("containsValueForKey for " + key + ": " + containsValueForKey);
-      try
-      {
-        if (isLocalInvalidate)
-        { // do a local invalidate
-          m_region.GetLocalView().Invalidate(key);
-        }
-        else
-        { // do a distributed invalidate
-          m_region.Invalidate(key);
-        }
-
-        // validation
-        if (isSerialExecution)
-        {
-          if (isEmptyClient)
-          {
-            if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-            {
-              verifySize(m_region,0);
-            }
-          }
-          else if (isThinClient)
-          { // we have eviction
-            if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-            {
-              verifySize(m_region,beforeSize);
-            }
-          }
-          else
-          { // region has all keys/values
-            verifyContainsKey(m_region,key, true);
-            verifyContainsValueForKey(m_region,key, false);
-            verifySize(m_region,beforeSize);
-          }
-          regionSnapshot[key] = default(TVal);
-          //regionSnapshot.Remove(key);
-          destroyedKeys.Remove(key);
-        }
-      }
-      catch (EntryNotFoundException e)
-      {
-        if (isSerialExecution)
-          throw new Exception(e.StackTrace);
-        else
-        {
-          Util.Log("Caught {0} (expected with concurrent execution); continuing with test", e);
-          return;
-        }
-      }
-    }
-/** Get an existing key in the given region if one is available,
- *  otherwise get a new key. 
- *
- *  @param aRegion The region to use for getting an entry.
- */
-    protected void getKey(IRegion<TKey, TVal> aRegion)
-    {
-      TKey key = GetExistingKey(isEmptyClient || isThinClient);
-      if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-      { // no existing keys; get a new key then
-        int size = aRegion.Count;
-        if (isSerialExecution && (size != 0))
-          throw new Exception("getExistingKey returned " + key + ", but region size is " + size);
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("getKey: No keys in region");
-        return;
-      }
-      int beforeSize = 0;
-      if (isEmptyClient || m_istransaction)
-        beforeSize = aRegion.Count;
-      else
-        beforeSize = aRegion.GetLocalView().Count;
-      bool beforeContainsValueForKey = aRegion.ContainsValueForKey(key);
-      bool beforeContainsKey = aRegion.ContainsKey(key);
-      TVal anObj = default(TVal);
-      try
-      {
-        anObj = aRegion[key];
-      }
-      catch (Apache.Geode.Client.KeyNotFoundException)
-      {
-        if (!EqualityComparer<TVal>.Default.Equals(anObj, default(TVal)))
-        {
-          throw new Apache.Geode.Client.KeyNotFoundException();
-        }
-
-      }
-      
-      // validation 
-      if (isSerialExecution)
-      {
-        if (isEmptyClient)
-        {
-          if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-          {
-            verifySize(aRegion, 0);
-          }
-        }
-        else if (isThinClient)
-        { // we have eviction
-          if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-          {
-            verifyContainsKey(aRegion, key, true);
-          }
-        }
-        else
-        { // we have all keys/values
-          verifyContainsKey(aRegion, key, true);
-          verifyContainsValueForKey(aRegion, key, (beforeContainsValueForKey));
-
-          // check the expected value of the get
-          TVal actualValue = anObj;
-          TVal expectedValue = default(TVal);
-          foreach( KeyValuePair<TKey, TVal> kvp in regionSnapshot )
-         {
-          TKey mapkey = kvp.Key;
-
-          if (key.Equals(mapkey))
-            {
-              expectedValue = kvp.Value;
-              if (!EqualityComparer<TVal>.Default.Equals(actualValue, default(TVal)))
-              {
-                if (!actualValue.Equals(expectedValue))
-                {
-                FwkException("getKey: expected value {0} is not same as actual value {1} for key {2}",
-                  expectedValue, actualValue, key);
-                }
-              } 
-            }
-          }
-          verifySize(aRegion, beforeSize);
-        }
-
-        // record the current state
-        // in case the get works like a put because there is a cacheLoader
-        regionSnapshot[key] = anObj;
-        destroyedKeys.Remove(key);
-      }
-    }
-
-    protected void destroyEntry(IRegion<TKey, TVal> m_region, bool isLocalDestroy)
-    {
-      TKey key = GetExistingKey(isEmptyClient || isThinClient);
-      if (EqualityComparer<TKey>.Default.Equals(key,default(TKey)))
-      {
-        int size = m_region.Count;
-        if (isSerialExecution && (size != 0))
-          throw new Exception("getExistingKey returned " + key + ", but region size is " + size);
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("destroyEntry: No keys in region");
-        return;
-      }
-      int beforeSize = 0;
-      if (isEmptyClient || m_istransaction)
-        beforeSize = m_region.Count;
-      else
-        beforeSize = m_region.GetLocalView().Count;
-      try
-      {
-        if (isLocalDestroy)
-        { // do a local invalidate
-          m_region.GetLocalView().Remove(key);
-        }
-        else
-        { // do a distributed invalidate
-          m_region.Remove(key);
-        }
-
-        // validation
-        if (isSerialExecution)
-        {
-          if (isEmptyClient)
-          {
-            if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-            {
-              verifySize(m_region,0);
-            }
-          }
-          else if (isThinClient)
-          { // we have eviction
-            if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-            {
-              verifyContainsKey(m_region,key, false);
-              verifyContainsValueForKey(m_region,key, false);
-              int afterSize = m_region.Count;
-              if ((afterSize != beforeSize) && (afterSize != beforeSize - 1))
-              {
-                throw new Exception("Expected region size " + afterSize + " to be either " +
-                    beforeSize + " or " + (beforeSize - 1));
-              }
-            }
-          }
-          else
-          { // region has all keys/values
-            verifyContainsKey(m_region,key, false);
-            verifyContainsValueForKey(m_region,key, false);
-            verifySize(m_region,beforeSize - 1);
-          }
-          regionSnapshot.Remove(key);
-          destroyedKeys.Add(key);
-        }
-      }
-      catch (EntryNotFoundException e)
-      {
-        if (isSerialExecution)
-          throw new Exception(e.StackTrace);
-        else
-        {
-          Util.Log("Caught {0} (expected with concurrent execution); continuing with test", e);
-          return;
-        }
-      }
-    }
-    protected void putAll(IRegion<TKey, TVal> r) 
-    {
-   // determine the number of new keys to put in the putAll
-   int beforeSize = 0;
-   if (isEmptyClient || m_istransaction)
-        beforeSize = r.Count;
-      else
-        beforeSize = r.GetLocalView().Count;
-   int localBeforeSize = r.GetLocalView().Count;
-   ResetKey("numPutAllExistingKeys");
-   ResetKey("numPutAllNewKeys");
-   int numNewKeysToPut = GetUIntValue("numPutAllNewKeys");
-  // get a map to put
-   IDictionary<TKey, TVal> mapToPut = new Dictionary<TKey,TVal>();
-      int valSize = GetUIntValue(ValueSizes);
-      int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-      valSize = ((valSize < minValSize) ? minValSize : valSize);
-      string valBuf = null;
-      valBuf = new string('A', valSize);
-      StringBuilder newKeys = new StringBuilder();
-        for (int i = 0; i < numNewKeysToPut; i++)
-        {
-          TKey key = GetNewKey();
-          TVal value = GetValue();
-          mapToPut[key] = value;
-          newKeys.Append(key + " ");
-          if ((i % 10) == 0) {
-            newKeys.Append("\n");
-          }
-        }
-     
-
-   // add existing keys to the map
-   int numPutAllExistingKeys =  GetUIntValue("numPutAllExistingKeys");
-   StringBuilder existingKeys = new StringBuilder();
-   if (numPutAllExistingKeys > 0) {
-         for (int i = 0; i < numPutAllExistingKeys; i++) { // put existing keys
-           TKey key = GetExistingKey(isEmptyClient || isThinClient);
-           TVal anObj = GetValue();
-            mapToPut[key] = anObj;
-            existingKeys.Append(key + " ");
-            if (((i+1) % 10) == 0) {
-               existingKeys.Append("\n");
-            }
-         }
-   }
-   FwkInfo("PR size is " + beforeSize + ", local region size is " +
-       localBeforeSize + ", map to use as argument to putAll is " + 
-       mapToPut.GetType().Name + " containing " + numNewKeysToPut + " new keys and " + 
-       numPutAllExistingKeys + " existing keys (updates); total map size is " + mapToPut.Count +
-       "\nnew keys are: " + newKeys + "\n" + "existing keys are: " + existingKeys);
-   
-
-   // do the putAll
-   FwkInfo("putAll: calling putAll with map of " + mapToPut.Count + " entries");
-   r.PutAll(mapToPut, TimeSpan.FromSeconds(60));
-
-   FwkInfo("putAll: done calling putAll with map of " + mapToPut.Count + " entries");
-
-   // validation
-   if (isSerialExecution) {
-     if (isEmptyClient) {
-       if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-       {
-         verifySize(r, 0);
-       }
-     }
-     else { // we have all keys/values in the local region
-      verifySize(r, beforeSize + numNewKeysToPut);
-     }
-     foreach (KeyValuePair<TKey, TVal> kvp in mapToPut)
-     {
-       TKey key = kvp.Key;
-       TVal value = kvp.Value;
-       if (!isEmptyClient && !isThinClient)
-       {
-         verifyContainsKey(r, key, true);
-         verifyContainsValueForKey(r, key, true);
-       }
-       regionSnapshot[key] = value;
-       destroyedKeys.Remove(key);
-      } 
-    }
-}
-    public void doEntryOps()
-    {
-      IRegion<TKey, TVal> region = GetRegion();
-      string opcode = null;
-      bool rolledback = false;
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 10 : secondsToRun;
-
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-      if (region == null)
-      {
-        FwkSevere("CacheServer.doEntryOps(): No region to perform operations on.");
-        now = end; // Do not do the loop
-      }
-      int size = 0;
-      int create = 0, update = 0, destroy = 0, invalidate = 0, localdestroy = 0, localinvalidate = 0,
-        get = 0, putall=0;
-      CacheTransactionManager txManager = null;
-      while (now < end)
-      {
-        rolledback = false;
-        try
-        {
-          if (isEmptyClient || m_istransaction)
-            size = region.Count;
-          else
-            size = region.GetLocalView().Count;
-        if (m_istransaction)
-        {
-          txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-          txManager.Begin();
-        }
-        opcode = GetStringValue("entryOps");
-        if (opcode == null) opcode = "no-opcode";
-        //int addKeyCount = Util.BBIncrement("CreateOpCount", "CreateKeyCount");
-        
-        if (((size < 1) && (opcode != "create")) || (opcode == "create"))
-        {
-          addEntry(region);
-          create++;
-        }
-        else if (opcode == "update")
-        {
-          updateEntry(region);
-          update++;
-        }
-        else if (opcode == "destroy")
-        {
-          destroyEntry(region,false);
-          destroy++;
-          //Util.BBDecrement("CreateOpCount", "CreateKeyCount");
-        }
-        else if (opcode == "localDestroy")
-        {
-          destroyEntry(region,true);
-          localdestroy++;
-        }
-        else if (opcode == "invalidate")
-        {
-          invalidateEntry(region,false);
-          invalidate++;
-          //Util.BBDecrement("CreateOpCount", "CreateKeyCount");
-        }
-        else if (opcode == "localInvalidate")
-        {
-          invalidateEntry(region, true);
-          localinvalidate++;
-        }
-        else if (opcode == "putAll")
-        {
-          putAll(region);
-          putall++;
-        }
-        else if (opcode == "get")
-        {
-          getKey(region);
-          get++;
-        }
-        else
-        {
-          FwkException("CacheServer.doEntryOps() Invalid operation " +
-            "specified: {0}", opcode);
-        }
-        //removeDuplicates(destroyedKeys);
-        if (m_istransaction && !rolledback)
-        {
-          try
-          {
-            txManager.Commit();
-          }
-          catch (CommitConflictException)
-          {
-            // can occur with concurrent execution
-            Util.Log("Caught CommitConflictException. Expected with concurrent execution, continuing test.");
-          }
-          catch (TransactionDataNodeHasDepartedException e)
-          {
-            throw e;
-          }
-          catch (Exception ex)
-          {
-            throw new Exception("Caught unexpected in doEntry : {0}", ex);
-          }
-        }
-        }
-        catch (TransactionDataNodeHasDepartedException e)
-        {
-          if (!m_istransaction)
-          {
-            throw new Exception("Unexpected Exception : {0}",e);
-          }
-          else
-          {
-            FwkInfo("Caught Exception " + e + ".  Expected with HA, continuing test.");
-            FwkInfo("Rolling back transaction.");
-            try
-            {
-              txManager.Rollback();
-              FwkInfo("Done Rolling back Transaction");
-            }
-            catch (Exception te)
-            {
-              FwkInfo("Caught exception {0} on rollback() after catching TransactionDataNodeHasDeparted during tx ops.  Expected, continuing test.",te);
-            }
-            rolledback = true;
-          }
-        } 
-        catch (Exception ex)
-        {
-          FwkException("CacheServer.doEntryOps() Caught unexpected " +
-            "exception during entry '{0}' operation: {1}.", opcode, ex);
-        }
-        now = DateTime.Now;
-      }
-      FwkInfo("DoEntryOP: create = {0}, update = {1}, destroy = {2}, localdestroy = {3}"
-         + ",invalidate = {4},localinvalidate = {5}, get = {6}, putall = {7}",
-        create, update, destroy, localinvalidate, invalidate, localinvalidate, get, putall);
-    }
-    public void DoRandomEntryOperation()
-    {
-      FwkInfo("In DoRandomEntryOperation");
-      try
-      {
-        int timedInterval = GetTimeValue("timedInterval") * 1000;
-        if (timedInterval <= 0)
-        {
-          timedInterval = 5000;
-        }
-        int maxTime = 10 * timedInterval;
-
-        // Loop over key set sizes
-        ResetKey("distinctKeys");
-        int numKeys = GetUIntValue("distinctKeys");
-        isSerialExecution = GetBoolValue("serialExecution");
-        string clntid = null;
-        int roundPosition = 0;
-        if (isSerialExecution)
-        {
-            regionSnapshot = new Dictionary<TKey, TVal>();
-            destroyedKeys = new List<TKey>();
-            Util.BBSet("RoundPositionBB", "roundPosition", 1);
-            roundPosition = (int)Util.BBGet("RoundPositionBB", "roundPosition");
-            clntid = String.Format("Client.{0}", roundPosition);
-            
-        }
-        else
-        {
-            clntid = Util.ClientId;
-        }
-        int numClients = GetUIntValue("clientCount");
-        string dummyClntid = null;
-        bool isdone = false;
-        Util.BBSet("RoundPositionBB", "done", false);
-        while (true)
-        {
-           if (roundPosition > numClients)
-            break;
-          try
-          {
-            if (clntid.Equals(Util.ClientId))
-            {
-              //RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-              if (isSerialExecution)
-              {
-                  doEntryOps();
-                  DoWaitForSilenceListenerComplete();
-                  Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-                  Util.BBSet("DestroyedKeys", "destroyedKeys", destroyedKeys);
-
-                  roundPosition = Util.BBIncrement("RoundPositionBB", "roundPosition");
-                  Util.BBSet("RoundPositionBB", "roundPosition", roundPosition);
-                  //clntid = String.Format("Client.{0}", roundPosition);
-                  Util.BBSet("RoundPositionBB", "done", true);
-                  Util.BBSet("RoundPositionBB", "VerifyCnt", 0);
-              }
-              else
-              {
-                  doEntryOps();
-                  break;
-              }
-              Thread.Sleep(2000);
-            }
-            else// if(!Util.ClientId.Equals(dummyClntid))G1326
-            {
-                for (; ; )
-                {
-                    isdone = (bool)Util.BBGet("RoundPositionBB", "done");
-                    if (isdone)
-                        break;
-                }
-                if (isdone)
-                {
-                  Thread.Sleep(35000);
-                  try
-                  {
-                      verifyFromSnapshot();
-                      Util.BBSet("RoundPositionBB", "done", false);
-                      Util.BBIncrement("RoundPositionBB", "VerifyCnt");     
-                  }
-                  catch (Exception ex)
-                    {
-                        Util.BBSet("RoundPositionBB", "done", false);
-                        Util.BBIncrement("RoundPositionBB", "VerifyCnt");
-                        Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-                        FwkException("In DoRandomEntryOperation() caught excption {0}.",ex.Message);
-                    }
-                                 
-                }
-                Thread.Sleep(100);
-              
-              
-            }
-            if (isSerialExecution)
-            {
-                int verifyCnt = (int)Util.BBGet("RoundPositionBB", "VerifyCnt");
-                while (verifyCnt < numClients - 1)
-                {
-                    verifyCnt = (int)Util.BBGet("RoundPositionBB", "VerifyCnt");
-                    Thread.Sleep(100);
-                }
-                //Util.BBSet("RoundPositionBB", "VerifyCnt", 0);
-                roundPosition = (int)Util.BBGet("RoundPositionBB", "roundPosition");
-                clntid = String.Format("Client.{0}", roundPosition);
-                dummyClntid = String.Format("Client.{0}", (roundPosition - 1));
-            }
-
-            Thread.Sleep(3000);
-          }
-          catch (ClientTimeoutException)
-          {
-            Util.BBSet("RoundPositionBB", "done", true);
-            Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-            FwkException("In DoRandomEntryOperation()  Timed run timed out.");
-          }
-          catch (Exception ex)
-          {
-            Util.BBSet("RoundPositionBB", "done", true);
-            Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-            FwkException("In DoRandomEntryOperation() caught excption {0}.",ex);
-          }
-          Thread.Sleep(3000);
-          
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRandomEntryOperation() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRandomEntryOperation() complete.");
-    }
-    public void doPopulateNewEntry()
-    {
-      IRegion<TKey,TVal> aRegion = GetRegion();
-      ResetKey("distinctKeys");
-      int numkeys = GetUIntValue("distinctKeys");
-      for(int i = 0;i<numkeys;i++)
-        addEntry(aRegion);
-    }
-    public void verifyFromSnapshot()
-    {
-      verifyFromSnapshotOnly();
-      //verifyInternalPRState();
-    }
-    public void verifyFromSnapshotOnly()
-    {
-      IRegion<TKey, TVal> aRegion = GetRegion();
-      if (isEmptyClient)
-      {
-        verifyServerKeysFromSnapshot();
-        return;
-      }/*
-      else if (isThinClient)
-      {
-        //verifyThinClientFromSnapshot();
-        verifyServerKeysFromSnapshot();
-        return;
-      }*/
-      StringBuilder aStr = new StringBuilder();
-      regionSnapshot = (Dictionary<TKey, TVal>)Util.BBGet("RegionSnapshot", "regionSnapshot");
-      int snapshotSize = regionSnapshot.Count;
-      int regionSize = 0;
-      if (isEmptyClient || m_istransaction)
-        regionSize = aRegion.Count;
-      else
-        regionSize = aRegion.GetLocalView().Count;
-      //int regionSize = aRegion.Count;// rjk this need to be uncommented if transaction is true.
-      //int regionSize = aRegion.GetLocalView().Count;
-      FwkInfo("Verifying from snapshot containing " + snapshotSize + " entries...");
-      if (snapshotSize != regionSize)
-      {
-        aStr.Append("Expected region " + aRegion.FullPath + " to be size " + snapshotSize +
-             ", but it is " + regionSize.ToString() + "\n");
-      }
-      foreach( KeyValuePair<TKey, TVal> kvp in regionSnapshot )
-      {
-        TKey key = kvp.Key;
-        TVal expectedValue = kvp.Value;
-        try
-        {
-          verifyContainsKey(aRegion, key, true);
-        }
-        catch (Exception e)
-        {
-          aStr.Append(e.Message + "\n");
-          //         anyFailures = true;
-        }
-        bool containsValueForKey = aRegion.GetLocalView().ContainsValueForKey(key);
-        try
-        {
-          verifyContainsValueForKey(aRegion, key, (expectedValue != null));
-        }
-        catch (Exception e)
-        {
-          aStr.Append(e.Message + "\n");
-        }
-
-        // do a get on the partitioned region if a loader won't get invoked; test its value
-        if (containsValueForKey)
-        {
-          // loader won't be invoked if we have a value for this key (whether or not a loader
-          // is installed), or if we don't have a loader at all
-          try
-          {
-            TVal actualValue = aRegion[key];
-            //if (!EqualityComparer<TVal>.Default.Equals(actualValue, default(TVal)))
-            //{
-            if (!actualValue.Equals(expectedValue))
-            {
-              FwkException("verifyFromSnapshotOnly: expected value {0} is not same as actual value {1} for key {3}",
-                expectedValue, actualValue, key);
-            }
-            //}
-          }
-          catch (Apache.Geode.Client.KeyNotFoundException)
-          {
-          }
-          catch (Exception e)
-          {
-            aStr.Append(e.Message + "\n");
-          }
-        }
-      }
-      if (isSerialExecution)
-      {
-        // check that destroyedKeys are not in the region
-        destroyedKeys = (List<TKey>)Util.BBGet("DestroyedKeys", "destroyedKeys");
-        for (int i = 0; i < destroyedKeys.Count; i++)
-        {
-          TKey key = destroyedKeys[i];
-          try
-          {
-            verifyContainsKey(aRegion, key, false);
-          }
-          catch (Exception e)
-          {
-            aStr.Append(e.Message + "\n");
-          }
-        }
-      }
-        try
-        {
-          verifyServerKeysFromSnapshot();
-        }
-        catch (Exception e)
-        {
-          aStr.Append(e.Message + "\n");
-        }
-      
-      if (aStr.Length > 0)
-      {
-        // shutdownHook will cause all members to dump partitioned region info
-        throw new Exception(aStr.ToString());
-      }
-      FwkInfo("Done verifying from snapshot containing " + snapshotSize.ToString() + " entries...");
-    }
-    
-    public void verifyServerKeysFromSnapshot()
-    {
-      IRegion<TKey, TVal> aRegion = GetRegion();
-      StringBuilder aStr = new StringBuilder();
-      regionSnapshot = (Dictionary<TKey, TVal>)Util.BBGet("RegionSnapshot", "regionSnapshot");
-      if(isSerialExecution)
-        destroyedKeys = (List<TKey>)Util.BBGet("DestroyedKeys", "destroyedKeys");
-      ICollection<TKey> serverKeys = new System.Collections.ObjectModel.Collection<TKey>();
-      foreach (TKey key in aRegion.Keys)
-        serverKeys.Add(key);
-
-      int snapshotSize = regionSnapshot.Count;
-      int numServerKeys = serverKeys.Count;
-      //int numServerKeys = aRegion.Count;
-      FwkInfo("Verifying server keys from snapshot containing " + snapshotSize.ToString() + " entries...");
-      if (snapshotSize != numServerKeys)
-      {
-        aStr.Append("Expected number of keys on server to be " + snapshotSize.ToString() + ", but it is " + numServerKeys.ToString() + "\n");
-      }
-      foreach (KeyValuePair<TKey, TVal> kvp in regionSnapshot)
-      { // iterating the expected keys
-        TKey key = kvp.Key;
-        TVal expectedValue = kvp.Value;
-        if (!serverKeys.Contains(key))
-        {
-          aStr.Append("Expected key " + key + " to be in server keys set, but it is missing\n");
-        }
-        else
-        {
-          // only do a get if we will not invoke the silence listener on a get
-          if ((!isThinClient && !isEmptyClient) ||
-              (isThinClient && aRegion.GetLocalView().ContainsKey(key)))
-          {
-            try
-            {
-            TVal valueOnServer = aRegion[key];
-            //if (!EqualityComparer<TVal>.Default.Equals(valueOnServer, default(TVal)))
-              //{
-                if (!valueOnServer.Equals(expectedValue))
-                {
-                  FwkException("verifyFromSnapshotOnly: expected value {0} is not same as actual value {1} for key {2}",
-                    expectedValue, valueOnServer,key);
-                }
-              //}
-            }
-            catch (Apache.Geode.Client.KeyNotFoundException)
-            {
-            }
-            catch (Exception e)
-            {
-              aStr.Append(e.Message + "\n");
-            }
-          }
-        }
-      }
-
-      // check that destroyedKeys are not in the server keys
-      if (isSerialExecution)
-      {
-        destroyedKeys = (List<TKey>)Util.BBGet("DestroyedKeys", "destroyedKeys");
-        for (int i = 0; i < destroyedKeys.Count; i++)
-        {
-          TKey key = destroyedKeys[i];
-          if (serverKeys.Contains(key))
-          {
-            aStr.Append("Destroyed key " + key + " was returned as a server key\n");
-          }
-        }
-
-
-        foreach (TKey key in regionSnapshot.Keys)
-        {
-          FwkInfo("IsReadOnly {0}", serverKeys.IsReadOnly);
-          FwkInfo("serverKeys  key {0}", key);
-          serverKeys.Remove(key);
-        }
-        if (serverKeys.Count != 0)
-        {
-          foreach (TKey key in serverKeys)
-          {
-            aStr.Append("Found the following unexpected keys in server keys: " +
-                        ": " + key + "\n");
-          }
-        }
-      }
-      if (aStr.Length > 0)
-      {
-        // shutdownHook will cause all members to dump partitioned region info
-        throw new Exception(aStr.ToString());
-      }
-      FwkInfo("Done verifying server keys from snapshot containing " + snapshotSize.ToString() + " entries...");
-    }
-    public void dumpDataOnBB()
-    {
-      IRegion<TKey, TVal> aRegion = GetRegion();
-      ICollection<TKey> serverkeys = aRegion.Keys;
-      //int expectedKeys = GetUIntValue("expectedKeys");
-      //if (expectedKeys != aRegion.Count)
-      //{
-      //  FwkException("CacheServerTest::dumpDataOnBB(): region count {0} is not same as expected size {0}", aRegion.Count, expectedKeys);
-      //}
-      regionSnapshot = new Dictionary<TKey, TVal>();
-      foreach (TKey key in serverkeys)
-      {
-          TVal value = default(TVal);;
-          try
-          {
-              value = aRegion[key];
-          }catch(Apache.Geode.Client.KeyNotFoundException){
-              value = default(TVal);
-          }
-          regionSnapshot[key] = value;
-      }
-      Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-    }
-    // Tx code end
-    public void DoEntryOperations()
-    {
-      FwkInfo("CacheServer.DoEntryOperations() called.");
-
-      int opsSec = GetUIntValue(OpsSecond);
-      opsSec = (opsSec < 1) ? 0 : opsSec;
-
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-      int valSize = GetUIntValue(ValueSizes);
-      int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-      valSize = ((valSize < minValSize) ? minValSize : valSize);
-
-      bool isCq = GetBoolValue("cq");
-          
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-
-      TKey key;
-      TVal value;
-      TVal tmpValue;
-      //TVal valBuf = (TVal)(object)Encoding.ASCII.GetBytes(new string('A', valSize));
-      byte[] valBuf = Encoding.ASCII.GetBytes(new string('A', valSize));
-      string opcode = null;
-
-      Int32 creates = 0, puts = 0, gets = 0, dests = 0, invals = 0, query = 0, putAll = 0, getAll = 0;
-      IRegion<TKey,TVal> region = GetRegion();
-      if (region == null)
-      {
-        FwkSevere("CacheServer.DoEntryOperations(): No region to perform operations on.");
-        now = end; // Do not do the loop
-      }
-
-      FwkInfo("CacheServer.DoEntryOperations() will work for {0}secs " +
-        "using {1} byte values.", secondsToRun, valSize);
-
-      PaceMeter pm = new PaceMeter(opsSec);
-      string objectType = GetStringValue(ObjectType);
-      bool multiRegion = GetBoolValue("multiRegion");
-      while (now < end)
-      {
-        try
-        {
-          opcode = GetStringValue(EntryOps);
-          if (opcode == null || opcode.Length == 0) 
-          {
-            opcode = "no-op";
-          }
-          if (multiRegion)
-          {
-            region = GetRegion();
-            if (region == null)
-            {
-              FwkException("CacheServerTest::doEntryOperations(): No region to perform operation {0}" , opcode);
-            }
-          }
-
-          key = (TKey)(object)GetKey(entryCount);
-          if (opcode == "add")
-          {
-              if (isCq)
-              {
-                  if (region.ContainsKey(key))
-                  {
-                      if (objectType != null && objectType.Length > 0)
-                      {
-                          tmpValue = GetUserObject(objectType);
-                      }
-                      else
-                      {
-                          int keyVal = int.Parse(key.ToString());
-                          int val = BitConverter.ToInt32(valBuf, 0);
-                          val = (val == keyVal) ? keyVal + 1 : keyVal;  // alternate the value so that it can be validated later.
-                          BitConverter.GetBytes(val).CopyTo(valBuf, 0);
-                          BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-                          tmpValue = (TVal)(object)valBuf;
-                      }
-                      region[key] = tmpValue;
-                      puts++;
-                      
-                  }
-                  else
-                  {
-                      if (objectType != null && objectType.Length > 0)
-                      {
-                          tmpValue = (TVal)(object)GetUserObject(objectType);
-                      }
-                      else
-                      {
-                          tmpValue = (TVal)(object)valBuf;
-                      }
-                      try
-                      {
-                          region.Add(key, tmpValue);
-                          creates++;
-                      }
-                      catch (EntryExistsException ex)
-                      {
-                          FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                               "exception in add: {0}", ex.Message);
-                      }
-                  }
-              }
-          }
-          else
-          {
-            if (opcode == "update")
-            {
-              if (objectType != null && objectType.Length > 0)
-              {
-                tmpValue = GetUserObject(objectType);
-              }
-              else
-              {
-                int keyVal = int.Parse(key.ToString());
-                int val = BitConverter.ToInt32(valBuf, 0);
-                val = (val == keyVal) ? keyVal + 1 : keyVal;  // alternate the value so that it can be validated later.
-                BitConverter.GetBytes(val).CopyTo(valBuf, 0);
-                BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-                tmpValue = (TVal)(object)valBuf;
-              }
-              region[key] = tmpValue;
-              puts++;
-            }
-            else if (opcode == "invalidate")
-            {
-                if (isCq)
-                {
-                    if (region.ContainsKey(key))
-                    {
-                        if (region.ContainsValueForKey(key))
-                        {
-                            try
-                            {
-                                region.Invalidate(key);
-                                invals++;
-                            }
-                            catch (EntryNotFoundException ex)
-                            {
-                                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                                  "exception in invalidate: {0}", ex.Message);
-                            }
-                        }
-
-                    }
-                }
-                else
-                {
-                  try
-                  {
-                    region.Invalidate(key);
-                    invals++;
-                  }
-                  catch (EntryNotFoundException ex)
-                  {
-                    FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                      "exception in invalidate: {0}", ex.Message);
-                  }
-                }
-            }
-            else if (opcode == "destroy")
-            {
-              try
-              {
-                region.Remove(key);
-                dests++;
-              }
-              catch (EntryNotFoundException ex)
-              {
-                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                  "exception in destroy: {0}", ex.Message);
-              }
-            }
-            else if (opcode == "read")
-            {
-              try {
-                value = (TVal)region[key];
-                gets++;
-              }
-              catch (EntryNotFoundException ex) {
-                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                  "exception in read: {0}", ex.Message);
-              }
-              catch (Apache.Geode.Client.KeyNotFoundException ex) {
-                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                  "exception in read: {0}", ex.Message);
-              }
-            }
-            else if (opcode == "read+localdestroy")
-            {
-              value = region[key];
-              gets++;
-              try
-              {
-                region.GetLocalView().Remove(key);
-                dests++;
-              }
-              catch (EntryNotFoundException ex)
-              {
-                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                  "exception in localDestroy: {0}", ex.Message);
-              }
-            }
-            else if (opcode == "query")
-            {
-              RunQuery();
-              query += 4;
-            }
-            else if (opcode == "putAll")
-            {
-              PutAllOps();
-              putAll++;
-            }
-            else if (opcode == "getAll")
-            {
-              GetAllOps();
-              getAll++;
-            }
-            else
-            {
-              FwkException("CacheServer.DoEntryOperations() Invalid operation " +
-                "specified: {0}", opcode);
-            }
-          }
-        }
-        catch (Exception ex)
-        {
-          FwkException("CacheServer.DoEntryOperations() Caught unexpected " +
-            "exception during entry '{0}' operation: {1}.", opcode, ex);
-        }
-        pm.CheckPace();
-        now = DateTime.Now;
-      }
-      key = default(TKey);
-      value = default(TVal);
-
-      FwkInfo("CacheServer.DoEntryOperations() did {0} creates, {1} puts, " +
-        "{2} gets, {3} invalidates, {4} destroys, {5} querys, {6} putAll, {7} getAll.",
-        creates, puts, gets, invals, dests, query, putAll, getAll);
-      Util.BBSet("OpsBB","CREATES",creates);
-      Util.BBSet("OpsBB","UPDATES",puts);
-      Util.BBSet("OpsBB","DESTROYS",dests);
-      Util.BBSet("OpsBB","GETS",gets);
-      Util.BBSet("OpsBB","INVALIDATES",invals);
-    }
-
-    
-
-    public void DoEntryOperationsForSecurity()
-    {
-      FwkInfo("CacheServer.DoEntryOperationsForSecurity() called.");
-      Util.RegisterTestCompleteDelegate(TestComplete);
-
-      int opsSec = GetUIntValue(OpsSecond);
-      opsSec = (opsSec < 1) ? 0 : opsSec;
-
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-      int valSize = GetUIntValue(ValueSizes);
-      int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-      valSize = ((valSize < minValSize) ? minValSize : valSize);
-
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-
-      TKey key;
-      TVal value;
-      TVal tmpValue;
-      byte[] valBuf = Encoding.ASCII.GetBytes(new string('A', valSize));
-
-      string opCode = null;
-
-      IRegion<TKey,TVal> region = GetRegion();
-      if (region == null)
-      {
-        FwkException("CacheServer.DoEntryOperationsForSecurity(): " +
-          "No region to perform operations on.");
-      }
-
-      FwkInfo("CacheServer.DoEntryOperationsForSecurity() will work for {0}secs " +
-        "using {1} byte values.", secondsToRun, valSize);
-
-      int cnt = 0;
-      int creates = 0, puts = 0, gets = 0, dests = 0, invals = 0, query = 0;
-      PaceMeter pm = new PaceMeter(opsSec);
-      string objectType = GetStringValue(ObjectType);
-      while (now < end)
-      {
-        int addOps = 1;
-        opCode = GetStringValue(EntryOps);
-        
-        try
-        {
-          UpdateOperationsMap(opCode, 1);
-          if (opCode == null || opCode.Length == 0)
-          {
-            opCode = "no-op";
-          }
-
-          key = GetKey(entryCount);
-          if (opCode == "create")
-          {
-            if (objectType != null && objectType.Length > 0)
-            {
-              tmpValue = GetUserObject(objectType);
-            }
-            else
-            {
-              tmpValue = (TVal)(object)valBuf;
-            }
-            region.Add(key, tmpValue);
-            creates++;
-          }
-          else
-          {
-            if (opCode == "update")
-            {
-              if (objectType != null && objectType.Length > 0)
-              {
-                tmpValue = (TVal)(object)GetUserObject(objectType);
-              }
-              else
-              {
-                int keyVal = int.Parse(key.ToString());
-                int val = BitConverter.ToInt32(valBuf, 0);
-                val = (val == keyVal) ? keyVal + 1 : keyVal;  // alternate the value so that it can be validated later.
-                BitConverter.GetBytes(val).CopyTo(valBuf, 0);
-                BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-                tmpValue = (TVal)(object)valBuf;
-              }
-              region[key] = tmpValue;
-              puts++;
-            }
-            else if (opCode == "invalidate")
-            {
-              region.Invalidate(key);
-              invals++;
-            }
-            else if (opCode == "destroy")
-            {
-              region.Remove(key);
-              dests++;
-            }
-            else if (opCode == "get")
-            {
-              value = (TVal)(object)region[key];
-              gets++;
-            }
-
-            else if (opCode == "getServerKeys")
-            {
-              ICollection<TKey> serverKeys = region.Keys;
-            }
-
-            else if (opCode == "read+localdestroy")
-            {
-              value = region[key];
-              gets++;
-              region.GetLocalView().Remove(key);
-              dests++;
-            }
-            else if (opCode == "regNUnregInterest")
-            {
-              TKey[] keys = new TKey[] { key };
-                region.GetSubscriptionService().RegisterKeys(keys);
-                region.GetSubscriptionService().UnregisterKeys(keys);
-            }
-            else if (opCode == "query")
-            {
-              var qs = CheckQueryService();
-              Query<object> qry = qs.NewQuery<object>("select distinct * from /Portfolios where FALSE");
-              ISelectResults<object> result = qry.Execute(TimeSpan.FromSeconds(600));
-              query++;
-            }
-            else if (opCode == "cq")
-            {
-              string cqName = String.Format("cq-{0}-{1}", Util.ClientId ,cnt++);
-              var qs = CheckQueryService();
-              CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-              ICqListener<TKey, object> cqLstner = new MyCqListener<TKey, object>();
-              cqFac.AddCqListener(cqLstner);
-              CqAttributes<TKey, object> cqAttr = cqFac.Create();
-              CqQuery<TKey, object> cq = qs.NewCq(cqName, "select * from /Portfolios where FALSE", cqAttr, false);
-              cq.Execute();
-              cq.Stop();
-              cq.Execute();
-              cq.Close();
-            }
-            else
-            {
-              FwkException("CacheServer.DoEntryOperationsForSecurity() " +
-                "Invalid operation specified: {0}", opCode);
-            }
-          }
-        }
-        catch (NotAuthorizedException)
-        {
-          //FwkInfo("Got expected NotAuthorizedException for operation {0}: {1}",
-          //  opCode, ex.Message);
-          UpdateExceptionsMap(opCode, 1);
-        }
-        catch (EntryExistsException)
-        {
-          addOps = -1;
-          UpdateOperationsMap(opCode, addOps);
-        }
-        catch (EntryNotFoundException)
-        {
-          addOps = -1;
-          UpdateOperationsMap(opCode, addOps);
-        }
-        catch (EntryDestroyedException)
-        {
-          addOps = -1;
-          UpdateOperationsMap(opCode, addOps);
-        }
-        catch (Apache.Geode.Client.KeyNotFoundException)
-        {
-          addOps = -1;
-          UpdateOperationsMap(opCode, addOps);
-        }
-        catch (TimeoutException ex)
-        {
-          FwkSevere("Caught unexpected timeout exception during entry {0} " +
-            " operation: {1}; continuing with test.", opCode, ex.Message);
-        }
-        catch (Exception ex)
-        {
-          FwkException("CacheServer.DoEntryOperationsForSecurity() Caught " +
-            "unexpected exception during entry '{0}' operation: {1}.",
-            opCode, ex);
-        }
-        pm.CheckPace();
-        now = DateTime.Now;
-      }
-      key = default(TKey);
-      value = default(TVal);
-      FwkInfo("CacheServer.DoEntryOperationsForSecurity() did {0} creates, {1} puts, " +
-        "{2} gets, {3} invalidates, {4} destroys, {5} querys.",
-        creates, puts, gets, invals, dests, query);
-    }
-
-    public void DoValidateEntryOperationsForSecurity()
-    {
-      bool isExpectedPass = GetBoolValue("isExpectedPass");
-      string opCode;
-      while ((opCode = GetStringValue(EntryOps)) != null)
-      {
-        int numOps = GetOpsFromMap(OperationsMap, opCode);
-        int notAuthzCount = GetOpsFromMap(ExceptionsMap, opCode);
-        if (isExpectedPass)
-        {
-          if (numOps != 0 && notAuthzCount == 0)
-          {
-            FwkInfo("Task passed sucessfully for operation {0} with total " +
-              "operations = {1}", opCode, numOps);
-          }
-          else
-          {
-            FwkException("{0} NotAuthorizedExceptions found for operation {1} " +
-              "while expected 0", notAuthzCount, opCode);
-          }
-        }
-        else
-        {
-          if (numOps == notAuthzCount)
-          {
-            FwkInfo("Operation {0} passed sucessfully and got the expected " +
-              "number of incorrect authorizations: {1}", opCode, numOps);
-          }
-          else
-          {
-            FwkException("For operation {0} expected number of " +
-              "NotAuthorizedExceptions is {1} but found {2}", opCode,
-              numOps, notAuthzCount);
-          }
-        }
-      }
-    }
-    //------------------------------------------------doOps for rvv -----------------
-      
-      public void DoRegisterInterestList()
-      {
-          FwkInfo("In DoRegisterInterestList()");
-          try
-          {
-              int entryCount = GetUIntValue("entryCount");
-              int numNewKeys = GetUIntValue("NumNewKeys");
-            /*
-              TKey[] registerKeyList = new TKey[entryCount + numNewKeys + NUM_EXTRA_KEYS];
-              for (int i = 0; i < entryCount + numNewKeys + NUM_EXTRA_KEYS; i++)
-              {
-                  registerKeyList[i] = m_KeysA[i];
-              }*/
-              IRegion<TKey, TVal> region = GetRegion();
-              FwkInfo("DoRegisterAllKeys() region name is {0}", region.Name);
-              bool isDurable = GetBoolValue("isDurableReg");
-              ResetKey("getInitialValues");
-              bool isGetInitialValues = GetBoolValue("getInitialValues");
-              bool isReceiveValues = true;
-              bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-              if (checkReceiveVal)
-              {
-                  ResetKey("receiveValue");
-                  isReceiveValues = GetBoolValue("receiveValue");
-              }
-              ResetKey("sleepBeforeRegisterInterest");
-              int sleepTime = GetUIntValue("sleepBeforeRegisterInterest");
-              sleepTime = sleepTime > 0 ? sleepTime : 0;
-              FwkInfo("Sleeping for " + sleepTime + " millis");
-              Thread.Sleep(sleepTime);
-              region.GetSubscriptionService().RegisterKeys(m_KeysA, isDurable, isGetInitialValues, isReceiveValues);
-              String durableClientId = CacheHelper<TKey, TVal>.DCache.SystemProperties.DurableClientId;
-              if (durableClientId.Length > 0)
-              {
-                  CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-              }
-          }
-          catch (Exception ex)
-          {
-              FwkException("DoRegisterInterestList() Caught Exception: {0}", ex);
-          }
-          FwkInfo("DoRegisterInterestList() complete.");
-      }
-
-      public void DoRegisterSingleKey()
-      {
-          FwkInfo("In DoRegisterSingleKey()");
-          try
-          {
-              
-            ExpectedRegionContents expected = null;
-               
-            string expectedcontentsRI_noops = GetStringValue("expectedRegionContents");
-            if(expectedcontentsRI_noops == "static_RI_noops_keysValues")
-                expected = expectedRgnContents[0];
-            else
-                expected = expectedRgnContents[2];
-              
-              int entryCount = GetUIntValue("entryCount");
-              int numNewKeys = GetUIntValue("NumNewKeys");
-              IRegion<TKey, TVal> region = GetRegion();
-              FwkInfo("DoRegisterAllKeys() region name is {0}", region.Name);
-              bool isDurable = GetBoolValue("isDurableReg");
-              ResetKey("getInitialValues");
-              bool isGetInitialValues = GetBoolValue("getInitialValues");
-              bool isReceiveValues = true;
-              bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-              if (checkReceiveVal)
-              {
-                  ResetKey("receiveValue");
-                  isReceiveValues = GetBoolValue("receiveValue");
-              }
-              ResetKey("sleepBeforeRegisterInterest");
-              int sleepTime = GetUIntValue("sleepBeforeRegisterInterest");
-              sleepTime = sleepTime > 0 ? sleepTime : 0;
-              FwkInfo("Sleeping for " + sleepTime + " millis");
-              Thread.Sleep(sleepTime);
-              //TKey[] registerKeyList = new TKey[entryCount + numNewKeys + NUM_EXTRA_KEYS];
-              List<TKey> templist = new List<TKey>();
-              for (int i = 0; i < entryCount + numNewKeys + NUM_EXTRA_KEYS; i++)
-              {
-                  templist.Add(m_KeysA[i]);
-                  region.GetSubscriptionService().RegisterKeys(templist, isDurable, isGetInitialValues, isReceiveValues);
-                  if (expected != null)
-                     verifyEntry(m_KeysA[i], expected);
-                  templist.Clear();
-              }
-              String durableClientId = CacheHelper<TKey, TVal>.DCache.SystemProperties.DurableClientId;
-              if (durableClientId.Length > 0)
-              {
-                  CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-              }
-          }
-          catch (Exception ex)
-          {
-              FwkException("DoRegisterSingleKey() Caught Exception: {0}", ex);
-          }
-          FwkInfo("DoRegisterSingleKey() complete.");
-      }
-
-    public void doFeedInt()
-    {
-      FwkInfo("CacheServer.doFeedInt() called.");
-
-      int entryCount = GetUIntValue("entryCount");
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-     try {
-        IRegion<TKey,TVal> region = GetRegion();
-        TVal value = default(TVal);
-        for(int i = 0;i < entryCount;i++){
-            value = GetValue((i + 1));
-            if (value != null)
-            {
-                if (region.ContainsKey(m_KeysA[i]))
-                    region[m_KeysA[i]] = value;
-                else 
-                region.Add(m_KeysA[i], value);
-            }
-        }
-      }catch(Exception ex)
-      {
-        FwkException("doFeedInt() Caught Exception: {0}", ex);
-      }
-      FwkInfo("doFeedInt() complete.");
-    }
-    private TVal GetValue()
-         {
-             return GetValue(null);
-         }
-
-    private TVal GetValue(object value)
-    {
-        TVal tmpValue = default(TVal);
-        FwkTest<TKey, TVal>.CurrentTest.ResetKey("valueSizes");
-        int size = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("valueSizes");
-        StringBuilder builder = new StringBuilder();
-        Random random = new Random();
-        char ch;
-        for (int j = 0; j < size; j++)
-        {
-            ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
-            builder.Append(ch);
-        }
-        FwkTest<TKey, TVal>.CurrentTest.ResetKey("objectType");
-        string m_objectType = FwkTest<TKey, TVal>.CurrentTest.GetStringValue("objectType");
-        //FwkTest<TKey, TVal>.CurrentTest.ResetKey("elementSize");
-        //int elementSize = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("elementSize");
-        FwkTest<TKey, TVal>.CurrentTest.ResetKey("versionNum");
-        int m_versionNum = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("versionNum"); //random.Next(2) + 1;// (counter++ % 2) + 1;
-        string sharedpath = (string)Util.BBGet("SharedPath", "sharedDir");
-        string m_sharePath = Path.Combine(sharedpath, "framework/csharp/bin");
-        if (typeof(TVal) == typeof(string))
-        {
-            tmpValue = (TVal)(object)builder.ToString();
-        }
-        else if (typeof(TVal) == typeof(byte[]))
-        {
-            tmpValue = (TVal)(object)(Encoding.ASCII.GetBytes(builder.ToString()));
-        }
-        else if (m_objectType != null)
-        {
-            if (m_objectType.Equals("PdxVersioned") && m_versionNum == 1)
-            {
-                PdxTests<TKey, TVal>.m_pdxVersionOneAsm = Assembly.LoadFrom(Path.Combine(m_sharePath, "PdxVersion1Lib.dll"));
-                Type pt = PdxTests<TKey, TVal>.m_pdxVersionOneAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-                tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, new object[] { value.ToString() });
-            }
-            else if (m_objectType.Equals("PdxVersioned") && m_versionNum == 2)
-            {
-                PdxTests<TKey, TVal>.m_pdxVersionTwoAsm = Assembly.LoadFrom(Path.Combine(m_sharePath, "PdxVersion2Lib.dll"));
-                Type pt = PdxTests<TKey, TVal>.m_pdxVersionTwoAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-                tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, new object[] { value.ToString() });
-            }
-            else if (m_objectType.Equals("Nested"))
-            {
-
-                tmpValue = (TVal)(object)new NestedPdx();
-            }
-            else if (m_objectType.Equals("PdxType"))
-            {
-                tmpValue = (TVal)(object)new PdxType();
-            }
-            /*else if (m_objectType.Equals("PdxInstanceFactory"))
-            {
-
-                tmpValue = createIpdxInstance();
-            }*/
-            else if (m_objectType.Equals("AutoSerilizer"))
-            {
-                tmpValue = (TVal)(object)new SerializePdx1(true);
-            }
-        }
-        else
-            tmpValue = (TVal)(object)value;
-        return tmpValue;
-
-    }
-    public void DoInitInstance() {
-	try {
-     ResetKey("entryCount");
-	int entryCount = GetUIntValue( "entryCount" );
-	entryCount = ( entryCount < 1 ) ? 10000 : entryCount;
-    ResetKey("NumNewKeys");
-	int numNewKeys = GetUIntValue( "NumNewKeys" );
-	//m_KeysA = new List<TKey>();
-	SetFisrtAndLastKeyOnBB(entryCount);
-	for(int cnt = 0;cnt < entryCount;cnt++){
-        m_KeysA.Add((TKey)(object)(cnt + 1));
-	}
-	 for (int i = entryCount; i < entryCount+numNewKeys; i++)
-         m_KeysA.Add((TKey)(object)(i + 1));
-	  // add some extra keys to the list that are never created by the test
-	 for (int i = entryCount+numNewKeys;i<entryCount+numNewKeys + NUM_EXTRA_KEYS; i++) // do a few more keys than we really need
-         m_KeysA.Add((TKey)(object)(i + 1));
-	 //static_RI_noops_keysValues 
-     //expectedRgnContents = new ExpectedRegionContents[4];
-     expectedRgnContents[0] = new ExpectedRegionContents(
-	       true,  true,  // none
-	       true,  true,  // invalidate
-	       true,  true,  // localInvalidate
-	       true,  true,  // destroy
-	       true,  true,  // localDestroy
-	       true,  true,  // update
-	       true,  true,  // get
-	       false, false, // newKey
-	       false,        // get allowed during validate
-           false);       // update has occurred
-        expectedRgnContents[0].exactSize(entryCount);
-	/* static_RI_noops_keys = new ExpectedRegionContents(
-	       true,  false,  // none
-	       true,  false,  // invalidate
-	       true,  false,  // localInvalidate
-	       true,  false,  // destroy
-	       true,  false,  // localDestroy
-	       true,  false,  // update
-	       true,  false,  // get
-	       false, false, // newKey
-	       false,        // get allowed during validate
-	       false);
-	 static_RI_noops_none = new ExpectedRegionContents(
-	       false, false,  // none
-	       false, false,  // invalidate
-	       false, false,  // localInvalidate
-	       false, false,  // destroy
-	       false, false,  // localDestroy
-	       false, false,  // update
-	       false, false,  // get
-	       false, false, // newKey
-	       false,        // get allowed during validate
-	       false);
-      */
-	 //static_RI_ops_keysValues 
-     expectedRgnContents[1] = new ExpectedRegionContents( // This is also valid for relicated function executions
-	 	       true,  true,  // none
-	 	       true,  false, // invalidate
-	 	       true,  true,  // localInvalidate
-	 	       false, false, // destroy
-	 	       true,  true,  // localDestroy
-	 	       true,  true,  // update
-	 	       true,  true,  // get
-	 	       true,  true,  // newKey
-	 	       true,         // get allowed during validate
-	 	       true);        // update has occurred
-     Int32 numDestroyed = (Int32)Util.BBGet("ImageBB", "Last_Destroy") - (Int32)Util.BBGet("ImageBB", "First_Destroy") + 1;
-     Int32 numInvalidated = (Int32)Util.BBGet("ImageBB", "Last_Invalidate") - (Int32)Util.BBGet("ImageBB", "First_Invalidate") + 1;
-     expectedRgnContents[1].exactSize(entryCount - numDestroyed + numNewKeys);
-	/* static_RI_ops_keys = new ExpectedRegionContents(
-	       true,  false, // none
-	       true,  false, // invalidate
-	       true,  false, // localInvalidate
-	       false, false, // destroy
-	       true,  false, // localDestroy
-	       true,  true,  // update
-	       true,  false, // get
-	       true,  true,  // newKey
-	       true,         // get allowed during validate
-	       true);        // update has occurred
-	 static_RI_ops_none = new ExpectedRegionContents(
-	       false, false, // none
-	       false, false, // invalidate
-	       false, false, // localInvalidate
-	       false, false, // destroy
-	       false, false, // localDestroy
-	       true,  true,  // update
-	       false, false, // get
-	       true,  true,  // newKey
-	       true,         // get allowed during validate
-	       true);        // update has occurred
-	       */
-	 //static_ops_RI_keysValues = 
-     expectedRgnContents[2] = new ExpectedRegionContents(
-	       true,  true,  // none
-	       true,  false, // invalidate
-	       true,  true,  // localInvalidate
-	       false, false, // destroy
-	       true,  true,  // localDestroy
-	       true,  true,  // update
-	       true,  true,  // get
-	       true,  true,  // newKey
-	       true,         // get allowed during validate
-	       true);        // update has occurred
-     expectedRgnContents[2].exactSize(entryCount - 2 * numDestroyed + numNewKeys + numInvalidated);
-	  //dynamicKeysValues
-           expectedRgnContents[3] = new ExpectedRegionContents(true, true, true);
-           expectedRgnContents[3].containsValue_invalidate(false);
-           expectedRgnContents[3].containsKey_destroy(false);
-           expectedRgnContents[3].containsValue_destroy(false);
-           expectedRgnContents[3].valueIsUpdated(true);
-           expectedRgnContents[3].exactSize(entryCount - numDestroyed + numNewKeys);
-
-           expectedRgnContents[4] = new ExpectedRegionContents( // Thit is for the same same client where we done ADD operation.
-              true, true,  // none
-              true, true,  // invalidate
-              true, true,  // localInvalidate
-              true, true,  // destroy
-              true, true,  // localDestroy
-              true, true,  // update
-              true, true,  // get
-              false, false, // newKey
-              true,        // get allowed during validate
-              false);       // update has occurred
-           expectedRgnContents[4].exactSize(entryCount);
-	 } catch ( Exception e ) {
-         FwkException("Caught unexpected exception during DoInitInstance " + e + " exiting task.");
-     }
-	 
-   }
-      public void DoResetImageBB()
-      {
-          ResetKey("entryCount");
-          int entryCount = GetUIntValue("entryCount");
-          SetFisrtAndLastKeyOnBB(entryCount);
-          Util.BBSet("ListenerBB", "lastEventTime", 0);
-    
-      }
-public void SetFisrtAndLastKeyOnBB(int entrycount  /* similar to numKeyIntervals on hydra*/)
-{
-        FwkInfo("In CacheServerTest::SetFisrtAndLastKeyOnBB");
-	   int count = 0; // 7 is num of ops ( create,update,get invalidate, local invalidate, destroy, local destroy )
-        bool m_istransaction = GetBoolValue( "useTransactions" );
-     if(m_istransaction){
-          count  = entrycount/5; // 5 is num of ops ( create,update,get invalidate,destroy )
-	  Util.BBSet("ImageBB", "First_LocalInvalidate",-1);
-	  Util.BBSet("ImageBB", "Last_LocalInvalidate",-1);
-	  Util.BBSet("ImageBB", "First_LocalDestroy",-1);
-	  Util.BBSet("ImageBB", "Last_LocalDestroy",-1);
-	  Util.BBSet("ImageBB","LASTKEY_LOCAL_INVALIDATE",1);
-	  Util.BBSet("ImageBB","LASTKEY_LOCAL_DESTROY",1);
-	  }
-        else {
-          count  = entrycount/7; // 7 is num of ops ( create,update,get invalidate, local invalidate, destroy, local destroy )
-          Util.BBSet("ImageBB", "First_LocalInvalidate",(5*count) +1);
-	  Util.BBSet("ImageBB", "Last_LocalInvalidate",6*count);
-	  Util.BBSet("ImageBB", "First_LocalDestroy",(6*count) +1);
-	  Util.BBSet("ImageBB", "Last_LocalDestroy",entrycount);
-	  Util.BBSet("ImageBB","LASTKEY_LOCAL_INVALIDATE",(5*count) +1);
-	  Util.BBSet("ImageBB","LASTKEY_LOCAL_DESTROY",(6*count) +1);
-	}
-	Util.BBSet("ImageBB", "First_None",1);
-	Util.BBSet("ImageBB", "Last_None",count);
-	Util.BBSet("ImageBB", "First_Invalidate",count +1);
-	Util.BBSet("ImageBB", "Last_Invalidate",2*count);
-    Util.BBSet("ImageBB", "First_Destroy",(2*count) +1);
-	Util.BBSet("ImageBB", "Last_Destroy",3*count);
-	Util.BBSet("ImageBB", "First_UpdateExistingKey",(3*count) +1);
-	Util.BBSet("ImageBB", "Last_UpdateExistingKey",4*count);
-	Util.BBSet("ImageBB", "First_Get",(4*count) +1);
-	Util.BBSet("ImageBB", "Last_Get",5*count);
-	Util.BBSet("ImageBB","NUM_NEW_KEYS_CREATED",1);
-	Util.BBSet("ImageBB","LASTKEY_UPDATE_EXISTING_KEY",(3*count) +1);
-	Util.BBSet("ImageBB","LASTKEY_INVALIDATE",(count) +1);
-	Util.BBSet("ImageBB","LASTKEY_DESTROY",(2*count) +1);
-	Util.BBSet("ImageBB","LASTKEY_GET",(4*count) +1);
-
-	FwkInfo(printKeyIntervalsBBData());
-}
-     
-public string printKeyIntervalsBBData( ) {
-    ResetKey("NumNewKeys");
-    ResetKey("entryCount");
-	int numNewKeys = GetUIntValue( "NumNewKeys" );
-	int numKeyIntervals = GetUIntValue( "entryCount" );
-    int numDestroyed = (int)Util.BBGet("ImageBB", "Last_Destroy") - (int)Util.BBGet("ImageBB", "First_Destroy") + 1;
-	totalNumKeys = numKeyIntervals + numNewKeys - numDestroyed;
-    StringBuilder attrsSB = new StringBuilder();
-    attrsSB.Append(Environment.NewLine + "keyIntervals read from blackboard = ");
-    attrsSB.Append(Environment.NewLine + "none: firstKey:" + Util.BBGet("ImageBB", "First_None") + 
-        ", lastKey: " + Util.BBGet("ImageBB", "Last_None"));
-    attrsSB.Append(Environment.NewLine + "invalidate: firstKey: " + Util.BBGet("ImageBB", "First_Invalidate") +
-        ", lastKey: " + Util.BBGet("ImageBB", "Last_Invalidate"));
-    attrsSB.Append(Environment.NewLine + "localInvalidate:  firstKey: " + Util.BBGet("ImageBB", "First_LocalInvalidate") +
-        ", lastKey: " + Util.BBGet("ImageBB", "Last_LocalInvalidate"));
-    attrsSB.Append(Environment.NewLine + "destroy: firstKey: " + Util.BBGet("ImageBB", "First_Destroy")+
-        ", lastKey: " + Util.BBGet("ImageBB", "Last_Destroy"));
-    attrsSB.Append(Environment.NewLine + "localDestroy: firstKey: " + Util.BBGet("ImageBB", "First_LocalDestroy") +
-        ", lastKey: " + Util.BBGet("ImageBB", "Last_LocalDestroy"));
-    attrsSB.Append(Environment.NewLine + "updateExistingKey: firstKey: " + Util.BBGet("ImageBB", "First_UpdateExistingKey") +
-        ", lastKey: " + Util.BBGet("ImageBB", "Last_UpdateExistingKey"));
-    attrsSB.Append(Environment.NewLine + "get: firstKey: " + Util.BBGet("ImageBB", "First_Get")+
-        ", lastKey: " + Util.BBGet("ImageBB", "Last_Get"));
-    attrsSB.Append(Environment.NewLine + "numKeyIntervals is  " + numKeyIntervals);
-    attrsSB.Append(Environment.NewLine + "numNewKeys is  " + numNewKeys);
-    attrsSB.Append(Environment.NewLine + "numDestroyed is " + numDestroyed);
-    attrsSB.Append(Environment.NewLine + "totalNumKeys is " + totalNumKeys);
-    attrsSB.Append(Environment.NewLine);
-
-    return attrsSB.ToString();
-}
-
-public void doRROps()
-{
-    FwkInfo("doRROps called.");
-    try
-    {
-      IRegion<TKey, TVal> region = GetRegion();
-      ResetKey("entryCount");
-      int entryCount = GetUIntValue("entryCount");
-      ResetKey("NumNewKeys");
-      int numNewKeys = GetUIntValue("NumNewKeys");
-      bool isdone = false;
-      Util.BBSet("RoundPositionBB", "done", false);
-      string clntid = null;
-      int roundPosition = 0;
-      bool isSerialEx = GetBoolValue("serialExecution");
-      if (isSerialEx)
-      {
-        Util.BBSet("RoundPositionBB", "roundPosition", 1);
-        roundPosition = (int)Util.BBGet("RoundPositionBB", "roundPosition");
-        clntid = String.Format("Client.{0}", roundPosition);
-      }
-      else
-      {
-        clntid = Util.ClientId;
-      }
-      int numClients = GetUIntValue("clientCount");
-      string dummyClntid = null;
-      ResetKey("numThreads");
-      int numThreads = GetUIntValue("numThreads");
-      while (true)
-      {
-        if (roundPosition > numClients)
-          break;
-        try
-        {
-            FwkInfo("clntid is = {0} Util.ClientId id is = {1} ",clntid,Util.ClientId);
-          if (clntid.Equals(Util.ClientId))
-          {
-            DoOpsTask<TKey, TVal> dooperation = new DoOpsTask<TKey, TVal>(region, m_istransaction);
-            if (isSerialEx)
-            {
-              RunTask(dooperation, numThreads, entryCount + numNewKeys + NUM_EXTRA_KEYS, -1, -1, null);
-              DoWaitForSilenceListenerComplete();
-              Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-              Util.BBSet("DestroyedKeys", "destroyedKeys", destroyedKeys);
-              roundPosition = Util.BBIncrement("RoundPositionBB", "roundPosition");
-              Util.BBSet("RoundPositionBB", "roundPosition", roundPosition);
-              Util.BBSet("RoundPositionBB", "done", true);
-              Util.BBSet("RoundPositionBB", "VerifyCnt", 0);
-            }
-            else
-            {
-              RunTask(dooperation, numThreads, entryCount + numNewKeys + NUM_EXTRA_KEYS, -1, -1, null);
-              break;
-            }
-            FwkInfo("Done DoOpsTask operation");
-          }
-          else// if(!Util.ClientId.Equals(dummyClntid))
-          {
-            for (; ; )
-            {
-              isdone = (bool)Util.BBGet("RoundPositionBB", "done");
-              if (isdone)
-                 break;
-            }
-            if (isdone)
-            {
-              //Thread.Sleep(35000);
-              try
-              {
-                //verifyFromSnapshot();
-                DoVerifyQueryResult();
-                Util.BBSet("RoundPositionBB", "done", false);
-                Util.BBIncrement("RoundPositionBB", "VerifyCnt");
-              }
-              catch (Exception ex)
-              {
-                Util.BBSet("RoundPositionBB", "done", false);
-                Util.BBIncrement("RoundPositionBB", "VerifyCnt");
-                Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-                FwkException("In DoRandomEntryOperation() caught excption {0}.", ex.Message);
-              }
-            }
-            Thread.Sleep(100);
-            FwkInfo("Done Verification and verifyCount = {0}", (int)Util.BBGet("RoundPositionBB", "VerifyCnt"));
-          }
-          if (isSerialEx)
-          {
-            int verifyCnt = (int)Util.BBGet("RoundPositionBB", "VerifyCnt");
-            FwkInfo("DoRandomOperation: verifyCnt {0}, numclient {1}", verifyCnt, numClients);
-            while (verifyCnt < numClients - 1)
-            {
-              verifyCnt = (int)Util.BBGet("RoundPositionBB", "VerifyCnt");
-              Thread.Sleep(100);
-            }
-            roundPosition = (int)Util.BBGet("RoundPositionBB", "roundPosition");
-            clntid = String.Format("Client.{0}", roundPosition);
-            dummyClntid = String.Format("Client.{0}", (roundPosition - 1));
-          }
-          Thread.Sleep(3000);
-        }
-        catch (ClientTimeoutException)
-        {
-          Util.BBSet("RoundPositionBB", "done", true);
-          Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-          FwkException("In DoRandomEntryOperation()  Timed run timed out.");
-        }
-        catch (Exception ex)
-        {
-          Util.BBSet("RoundPositionBB", "done", true);
-          Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-          FwkException("In DoRandomEntryOperation() caught excption {0}.", ex.Message);
-        }
-        Thread.Sleep(3000);
-      }
-    }
-    catch (Exception ex)
-    {
-        FwkException("last DoRandomEntryOperation() Caught Exception: {0}", ex.Message);
-    }
-    FwkInfo("DoRandomEntryOperation() complete.");
-}
-
-public void doOps()
-{
-    FwkInfo("doOps called.");
-
-    ResetKey("entryCount");
-    int entryCount = GetUIntValue("entryCount");
-    ResetKey("NumNewKeys");
-    int numNewKeys = GetUIntValue("NumNewKeys");
-
-    //TestClient * clnt = TestClient::getTestClient();
-    IRegion<TKey, TVal> regionPtr = GetRegion();
-    if (regionPtr == null)
-    {
-        FwkSevere("CacheServerTest::doOps(): No region to perform operations on.");
-        //now = end; // Do not do the loop
-    }
-    ResetKey("useTransactions");
-    bool m_istransaction = GetBoolValue("useTransactions");
-    try
-    {
-        DoOpsTask<TKey, TVal> dooperation = new DoOpsTask<TKey, TVal>(regionPtr, m_istransaction);
-        ResetKey("numThreads");
-        int numThreads = GetUIntValue("numThreads");
-        RunTask(dooperation, numThreads, entryCount + numNewKeys + NUM_EXTRA_KEYS, -1, -1, null);
-    }
-    catch (ClientTimeoutException)
-    {
-        FwkException("In doOps()  Timed run timed out.");
-    }
-    catch (Exception e)
-    {
-        FwkException("Caught unexpected exception during doOps: " + e);
-    }
-    FwkInfo("Done in doOps");
-    Thread.Sleep(10000);
-}
-
-
-public void DoVerifyQueryResult()
-{
-  FwkInfo("verifyQueryResult() called");
-  string query = GetStringValue("query");
-  IRegion<TKey, TVal> region = GetRegion();
-  var resultSize = region.Count;
-  bool isSerial = GetBoolValue("serialExecution");
-  Int32 localInvalidate = 0;
-  if (isSerial)
-  { localInvalidate = (Int32)Util.BBGet("ImageBB", "Last_LocalInvalidate") - (Int32)Util.BBGet("ImageBB", "First_LocalInvalidate") + 1; }
-  FwkInfo("localInvalidate size is {0}", localInvalidate);
-  while (query != null && query.Length > 0)
-  {
-      var qs = CheckQueryService();
-      DateTime startTime;
-      TimeSpan elapsedTime;
-      ISelectResults<object> results;
-      string CqName = String.Format("_default{0}", query);
-      CqQuery<TKey, object> cq = qs.GetCq<TKey, object>(CqName);
-      try
-      {
-        if (cq.IsRunning())
-        {
-          cq.Stop();
-        }
-      }
-      catch (IllegalStateException ex)
-      {
-        FwkException("Caught {0} while stopping cq", ex.Message);
-      }
-      startTime = DateTime.Now;
-      results = cq.ExecuteWithInitialResults(QueryResponseTimeout);
-      elapsedTime = DateTime.Now - startTime;
-      if ((resultSize - localInvalidate) != (int) results.Size)
-      {
-        FwkSevere("ReadQueryString: Result size found {0}, expected {1}.",
-           results.Size, (resultSize - localInvalidate));
-      }
-      FwkInfo("ReadQueryString: Time Taken to execute the CqQuery [{0}]:" +
-        "{1}ms ResultSize Size = {2}", query, elapsedTime.TotalMilliseconds, results.Size);
-      FwkInfo("ReadQueryString: Got expected result size {0}.",
-          results.Size);
-      query = GetStringValue("query");
-    } 
- }
-
-
-/*public void doOps()
-{
-  FwkInfo( "doOps called." );
-
-  ResetKey("entryCount");
-  int entryCount = GetUIntValue( "entryCount" );
-  ResetKey("NumNewKeys");
-  int numNewKeys = GetUIntValue( "NumNewKeys" );
-
-  //TestClient * clnt = TestClient::getTestClient();
-  IRegion<TKey,TVal> regionPtr = GetRegion();
-   if (regionPtr == null) {
-    FwkSevere( "CacheServerTest::doOps(): No region to perform operations on." );
-    //now = end; // Do not do the loop
-  }
-  ResetKey("useTransactions");
-  bool m_istransaction = GetBoolValue("useTransactions");
-  try
-  {
-      DoOpsTask<TKey, TVal> dooperation = new DoOpsTask<TKey, TVal>(regionPtr, m_istransaction);
-      ResetKey("numThreads");
-      int numThreads = GetUIntValue("numThreads");
-      RunTask(dooperation, numThreads, entryCount+numNewKeys + NUM_EXTRA_KEYS, -1, -1, null);
-  }
-  catch (ClientTimeoutException)
-  {
-      FwkException("In doOps()  Timed run timed out.");
-  }
-  catch (Exception e)
-  {
-      FwkException("Caught unexpected exception during doOps: " + e);
-  }
- 
-
-  FwkInfo("Done in doOps");
-  Thread.Sleep( 10000 );
- }
-*/
-private CacheableHashSet verifyRegionSize(ExpectedRegionContents expectedRgnContents)
-{
-	IRegion<TKey,TVal> region = GetRegion();
-    int numKeys = region.GetLocalView().Count;
-	  //int expectedNumKeys = getIntValue( "expectedValue" );
-      ResetKey("entryCount");
-      ResetKey("NumNewKeys");
-	  int entryCount = GetUIntValue( "entryCount" );
-	  int numNewKeys = GetUIntValue( "NumNewKeys" );
-      FwkInfo("Expecting exact size of region " + expectedRgnContents.exactSize());
-      if (expectedRgnContents.exactSize() != numKeys)
-      {
-          FwkException("Expected " + expectedRgnContents.exactSize() + " keys, but there are " + numKeys);
-	  }
-    
-	  CacheableHashSet keysToCheck = CacheableHashSet.Create();
-	  for(int i = 0;i<entryCount+numNewKeys + NUM_EXTRA_KEYS;i++)
-		    keysToCheck.Add(m_KeysA[i]);// check all keys in the keyList (including "extra" keys not in server)
-
-	  ICollection<TKey> keyVec = region.GetLocalView().Keys;
-      foreach (TKey cKey in keyVec)
-	  	  keysToCheck.Add(cKey);// also check any keys in the region that are not in the keyList
-	  /*if (isGetInitialValues)
-	       expected = static_RI_ops_keysValues;
-	     else
-	       expected = static_RI_ops_none;
-      */
-	  return keysToCheck;
-}
-      public void DoVerifyRegionContentsBeforeOpsOnFeederClient()
-      {
-          FwkInfo("DoVerifyRegionContentsBeforeOpsOnFeederClient called.");
-          FwkInfo("DoVerifyRegionContentsBeforeOpsOnFeederClient called expected ." + expectedRgnContents[4].toString());
-          IRegion<TKey, TVal> region = GetRegion();
-          int numKeys = region.Count;
-          ResetKey("entryCount");
-          int entryCount = GetUIntValue("entryCount");
-          if (expectedRgnContents[4].exactSize() != numKeys)
-          {
-              FwkException("Expected " + expectedRgnContents[4].exactSize() + " keys, but there are " + numKeys);
-          }
-          CacheableHashSet keysToCheck = CacheableHashSet.Create();
-          for (int i = 0; i < entryCount; i++)
-              keysToCheck.Add(m_KeysA[i]);
-          foreach (TKey key in keysToCheck)
-          {
-              try
-              {
-                  verifyEntry(key, expectedRgnContents[4]);
-              }
-              catch (Exception e)
-              {
-                  FwkException("Caught unexpected exception for key " + key + " during DoVerifyRegionContentsBeforeOpsOnFeederClient " + e);
-              }
-          }
-
-      }
-
-public void DoVerifyRegionContentsBeforeOps()
-{
-  FwkInfo( "verifyRegionContentsBeforeOps called." );
-  FwkInfo("DoVerifyRegionContentsBeforeOps called expected ." + expectedRgnContents[0].toString());
-  CacheableHashSet keysToCheck = verifyRegionSize(expectedRgnContents[0]);
-  foreach (TKey key in keysToCheck)
-  {
-	  try {
-          verifyEntry(key, expectedRgnContents[0]);
-	   } catch (Exception e) {
-           FwkException("Caught unexpected exceptionfor key " + key + " during verifyRegionContentsBeforeOps " + e);
-	   }
-  }
- 
-}
-
-public void doVerifyRegionContentsAfterLateOps()
-{
-  FwkInfo( "verifyRegionContentsAfterLateOps called." );
-  FwkInfo("doVerifyRegionContentsAfterLateOps called expected ." + expectedRgnContents[1].toString());
-  CacheableHashSet keysToCheck = verifyRegionSize(expectedRgnContents[1]);
-
-  foreach (TKey key in keysToCheck)
-  {
-	  try {
-          verifyEntry(key, expectedRgnContents[1]);
-	   } catch (Exception e) {
-           FwkException("Caught unexpected exception  for key " + key + " during verifyRegionContentsAfterLateOps " + e);
-	   }
-  }
-}
-
-      public void doVerifyRegionContentsAfterOpsRI()
-      {
-          FwkInfo("doVerifyRegionContentsAfterOpsRI called.");
-          if (expectedRgnContents != null)
-              FwkInfo("doVerifyRegionContentsAfterOpsRI called expected ." + expectedRgnContents[2].toString());
-          else
-              FwkInfo("doVerifyRegionContentsAfterOpsRI called expected is null");
-          CacheableHashSet keysToCheck = verifyRegionSize(expectedRgnContents[2]);
-          foreach (TKey key in keysToCheck)
-          {
-              try
-              {
-                  verifyEntry(key, expectedRgnContents[2]);
-              }
-              catch (Exception e)
-              {
-                  FwkException("Caught unexpected exception  for key " + key + " during doVerifyRegionContentsAfterOpsRI " + e);
-              }
-          }
-      }
-      public void doVerifyRegionContentsDynamic()
-      {
-          FwkInfo("doVerifyRegionContentsDynamic called.");
-          FwkInfo("doVerifyRegionContentsDynamic called expected ." + expectedRgnContents[3].toString());
-          CacheableHashSet keysToCheck = verifyRegionSize(expectedRgnContents[3]);
-          foreach (TKey key in keysToCheck)
-          {
-              try
-              {
-                  verifyEntry(key, expectedRgnContents[3]);
-              }
-              catch (Exception e)
-              {
-                  FwkException("Caught unexpected exception  for key " + key + " during doVerifyRegionContentsDynamic " + e);
-              }
-          }
-      }
-
-      public void DoVerifyRegionContents()
-      {
-
-          ResetKey("entryCount");
-          ResetKey("NumNewKeys");
-          int numNewKeys = GetUIntValue("NumNewKeys");
-          int entryCount = GetUIntValue("entryCount");
-          Int32 numDestroyed = (Int32)Util.BBGet("ImageBB", "Last_Destroy") - (Int32)Util.BBGet("ImageBB", "First_Destroy") + 1;
-
-          totalNumKeys = entryCount + numNewKeys - numDestroyed;
-          IRegion<TKey, TVal> regionPtr = GetRegion();
- 
-          TKey[] keys = (TKey[])regionPtr.Keys;
-          //Int32 numKeys = regionPtr.Count;
-          if (totalNumKeys != keys.Length)
-          {
-              FwkException("Expected " + totalNumKeys + " keys, but there are " + keys.Length);
-          }
-          try
-          {
-              for (int ii = 0; ii < (entryCount + numNewKeys); ii++)
-              {
-                  TKey key = m_KeysA[ii];
-                  int i = ii + 1;
-                  if ((i >= (int)Util.BBGet("ImageBB", "First_None")) &&
-                            (i <= (int)Util.BBGet("ImageBB", "Last_None")) ||
-                            (i >= (int)Util.BBGet("ImageBB", "First_Get")) &&
-                             (i <= (int)Util.BBGet("ImageBB", "Last_Get")))
-                  {
-                      checkContainsKey(key, true, "key was untouched");
-                      checkContainsValueForKey(key, true, "key was untouched");
-                      TVal value = regionPtr[key];
-                      checkValue(key, value);
-
-                  }
-
-                  else if ((i >= (int)Util.BBGet("ImageBB", "First_Invalidate")) &&
-                          (i <= (int)Util.BBGet("ImageBB", "Last_Invalidate")))
-                  {
-                      checkContainsKey(key, true, "key was invalidated ");
-                      checkContainsValueForKey(key, false, "key was invalidated ");
-
-                  }
-                  else if ((i >= (int)Util.BBGet("ImageBB", "First_LocalInvalidate")) &&
-                        (i <= (int)Util.BBGet("ImageBB", "Last_LocalInvalidate")))
-                  {
-                      // this key was locally invalidated
-                      checkContainsKey(key, true, "key was locally invalidated");
-                      checkContainsValueForKey(key, true, "key was locally invalidated");
-
-                      try
-                      {
-                          TVal value = regionPtr[key];
-                          checkValue(key, value);
-                      }
-                      catch (Apache.Geode.Client.KeyNotFoundException)
-                      { }
-
-                  }
-                  else if ((i >= (int)Util.BBGet("ImageBB", "First_Destroy")) &&
-                     (i <= (int)Util.BBGet("ImageBB", "Last_Destroy")))
-                  {
-                      // this key was destroyed
-                      checkContainsKey(key, false, "key was destroyed");
-                      checkContainsValueForKey(key, false, "key was destroyed");
-
-                  }
-                  else if ((i >= (int)Util.BBGet("ImageBB", "First_LocalDestroy")) &&
-                        (i <= (int)Util.BBGet("ImageBB", "Last_LocalDestroy")))
-                  {
-                      // this key was locally destroyed
-                      checkContainsKey(key, true, "key was locally destroyed");
-                      checkContainsValueForKey(key, true, "key was locally destroyed");
-
-                      TVal value = regionPtr[key];
-                      checkValue(key, value);
-
-                  }
-                  else if ((i >= (int)Util.BBGet("ImageBB", "First_UpdateExistingKey")) &&
-                        (i <= (int)Util.BBGet("ImageBB", "Last_UpdateExistingKey")))
-                  {
-                      // this key was updated
-                      checkContainsKey(key, true, "key was updated");
-                      checkContainsValueForKey(key, true, "key was updated");
-
-                      TVal value = regionPtr[key];
-                      checkUpdatedValue(key, value);
-
-                  }
-                  else if ((i > entryCount) && (i <= (entryCount + numNewKeys)))
-                  {
-                      // key was newly added
-                      checkContainsKey(key, true, "key was new");
-                      checkContainsValueForKey(key, true, "key was new");
-
-                      TVal value = regionPtr[key];
-                      checkValue(key, value);
-
-                  }
-                  else
-                  { // key is outside of keyIntervals and new keys; it was never loaded
-                      // key was never loaded
-                      checkContainsKey(key, false, "key was never used");
-                      checkContainsValueForKey(key, false, "key was never used");
-                  }
-              }
-          }
-          catch (Exception e)
-          {
-              FwkException("Caught unexpected exception  during doVerifyRegionContents: " + e);
-          }
-      }
-      public void verifyEntry(TKey key, ExpectedRegionContents expectedRgnContents)
-      {
-        int i = 0;
-        if(typeof(TKey) == typeof(int))
-            i = (int)(object)key;
-        
-        
-        int numNewKeys = GetUIntValue( "NumNewKeys" );
-
-        int entryCount = GetUIntValue("entryCount");
-        ResetKey("entryCount");
-        ResetKey("NumNewKeys");
-        IRegion<TKey, TVal> regionPtr = GetRegion();
-        if ((i >= (int)Util.BBGet("ImageBB", "First_None")) &&
-                  (i <= (int)Util.BBGet("ImageBB", "Last_None")))
-        {
-            checkContainsKey(key, expectedRgnContents.containsKey_none(), "key was untouched");
-          checkContainsValueForKey(key, expectedRgnContents.containsValue_none(), "key was untouched");
-          if (expectedRgnContents.getAllowed_none())
-          {
-              TVal value = regionPtr[key];
-              checkValue(key, value);
-          }
-      }
-      else if ((i >= (int)Util.BBGet("ImageBB", "First_Get")) &&
-                   (i <= (int)Util.BBGet("ImageBB", "Last_Get")))
-      {
-          // this key was untouched after its creation
-          checkContainsKey(key, expectedRgnContents.containsKey_get(), "get key");
-          checkContainsValueForKey(key, expectedRgnContents.containsValue_get(), "get key");
-          if (expectedRgnContents.getAllowed_get())
-          {
-              TVal value = regionPtr[key];
-             checkValue(key, value);
-          }
-      }
-      else if ((i >= (int)Util.BBGet("ImageBB", "First_Invalidate")) &&
-    (i <= (int)Util.BBGet("ImageBB", "Last_Invalidate")))
-      {
-          checkContainsKey(key, expectedRgnContents.containsKey_invalidate(), "key was invalidated (Bug 35303)");
-          bool expectValue = expectedRgnContents.containsValue_invalidate();
-          checkContainsValueForKey(key, expectValue, "key was invalidated (Bug 35303)");
-          if (expectedRgnContents.getAllowed_invalidate())
-          {
-              try
-              {
-                  TVal value = regionPtr[key];
-                  if (expectValue)
-                  {
-                      checkValue(key, value);
-                  }
-                  else
-                  {
-                      if (value != null)
-                      {
-                          throw new Exception("Bug 35303, after calling get " + key.ToString() + ", expected invalidated value to be null but it is " + value.ToString());
-                      }
-                  }
-              }
-              catch (Apache.Geode.Client.KeyNotFoundException)
-              {}
-          }
-      }
-      else if ((i >= (int)Util.BBGet("ImageBB", "First_LocalInvalidate")) &&
-    (i <= (int)Util.BBGet("ImageBB", "Last_LocalInvalidate")))
-      {
-          // this key was locally invalidated
-          checkContainsKey(key, expectedRgnContents.containsKey_localInvalidate(), "key was locally invalidated");
-          checkContainsValueForKey(key, expectedRgnContents.containsValue_localInvalidate(), "key was locally invalidated");
-          if (expectedRgnContents.getAllowed_localInvalidate())
-          {
-              try
-              {
-                  TVal value = regionPtr[key];
-                  checkValue(key, value);
-              }
-              catch (Apache.Geode.Client.KeyNotFoundException)
-              { }
-          }
-      }
-      else if ((i >= (int)Util.BBGet("ImageBB", "First_Destroy")) &&
-    (i <= (int)Util.BBGet("ImageBB", "Last_Destroy")))
-      {
-          // this key was destroyed
-          checkContainsKey(key, expectedRgnContents.containsKey_destroy(), "key was destroyed");
-          bool expectValue = expectedRgnContents.containsValue_destroy();
-          checkContainsValueForKey(key, expectValue, "key was destroyed");
-          if (expectedRgnContents.getAllowed_destroy())
-          {
-              try
-              {
-                  TVal value = regionPtr[key];
-                  if (expectValue)
-                  {
-                      checkValue(key, value);
-                  }
-                  else
-                  {
-                      if (value != null)
-                      {
-                          throw new Exception("Expected value for " + key.ToString() + " to be null");
-                      }
-                  }
-              }
-              catch (Apache.Geode.Client.KeyNotFoundException)
-              { }
-          }
-      }
-      else if ((i >= (int)Util.BBGet("ImageBB", "First_LocalDestroy")) &&
-    (i <= (int)Util.BBGet("ImageBB", "Last_LocalDestroy")))
-      {
-          // this key was locally destroyed
-          checkContainsKey(key, expectedRgnContents.containsKey_localDestroy(), "key was locally destroyed");
-          checkContainsValueForKey(key, expectedRgnContents.containsValue_localDestroy(), "key was locally destroyed");
-          if (expectedRgnContents.getAllowed_localDestroy())
-          {
-              TVal value = regionPtr[key];
-             checkValue(key, value);
-          }
-      }
-      else if ((i >= (int)Util.BBGet("ImageBB", "First_UpdateExistingKey")) &&
-    (i <= (int)Util.BBGet("ImageBB", "Last_UpdateExistingKey")))
-      {
-          // this key was updated
-          checkContainsKey(key, expectedRgnContents.containsKey_update(), "key was updated");
-          checkContainsValueForKey(key, expectedRgnContents.containsValue_update(), "key was updated");
-          if (expectedRgnContents.getAllowed_update())
-          {
-              TVal value = regionPtr[key];
-              if (expectedRgnContents.valueIsUpdated())
-              {
-                checkUpdatedValue(key, value);
-             } else {
-                checkValue(key, value);
-             }
-          }
-       } else if ((i > entryCount) && (i <= (entryCount + numNewKeys))) {
-          // key was newly added
-           checkContainsKey(key, expectedRgnContents.containsKey_newKey(), "key was new");
-           checkContainsValueForKey(key, expectedRgnContents.containsValue_newKey(), "key was new");
-           if (expectedRgnContents.getAllowed_newKey())
-           {
-              TVal value = regionPtr[key];
-             checkValue(key, value);
-          }
-       } else { // key is outside of keyIntervals and new keys; it was never loaded
-         // key was never loaded
-         checkContainsKey(key, false, "key was never used");
-         checkContainsValueForKey(key, false, "key was never used");
-       }
-}
-
-private void checkContainsKey(TKey key, bool expected, string logStr){
-   IRegion<TKey,TVal> region = GetRegion();
-   bool containsKey = false;
-   if (region.Attributes.CachingEnabled == true)
-       containsKey = region.GetLocalView().ContainsKey(key);
-   else
-       containsKey = region.ContainsKey(key);
-   if (containsKey != expected) {
-	   FwkException("Expected containsKey(" + key.ToString() + ") to be " + expected +
-			   ", but it was " + containsKey + ": " + logStr);
-   }
-
-}
-private void checkContainsValueForKey(TKey key, bool expected,string logStr) {
-   IRegion<TKey,TVal> region = GetRegion();
-    bool containsValue = false;
-    if (region.Attributes.CachingEnabled == true)
-        containsValue = region.GetLocalView().ContainsValueForKey(key);
-    else
-        containsValue = region.ContainsValueForKey(key);
-   if (containsValue != expected){
-      FwkException("Expected containsValueForKey(" + key.ToString() + ") to be " + expected +
-                ", but it was " + containsValue + ": " + logStr);
-  }
-}
-
-private void checkValue(TKey key, TVal value)
-{
-    ResetKey("versionNum");
-    int versionnum = GetUIntValue("versionNum");
-    Type typ = value.GetType();
-    if (typ == typeof(int))
-    {
-        if (!key.Equals(value))
-            throw new Exception("Inconsistent Value for key " + key.ToString() + " Expected Value should be " + value.ToString());
-    }
-    else if (versionnum ==1 &&  (typ == PdxTests<TKey, TVal>.m_pdxVersionOneAsm.GetType("PdxVersionTests.PdxVersioned")))
-    {
-        string expectedValue = string.Format("PdxVersioned {0}",  key);
-        //typ val = (typ.)value;
-        object val = typ.GetProperty("PString").GetValue(value, null);
-        if (!expectedValue.Equals(val.ToString()))
-        {
-            throw new Exception("Inconsistent Value for key " + key.ToString() + " Expected Value should be " + expectedValue +
-                " but recevied value is " + val.ToString());
-        }
-    }
-    else if (versionnum == 2 && (typ == PdxTests<TKey, TVal>.m_pdxVersionTwoAsm.GetType("PdxVersionTests.PdxVersioned")))
-    {
-        string expectedValue = string.Format("PdxVersioned {0}", key);
-        //typ val = (typ.)value;
-        object val = typ.GetProperty("PString").GetValue(value, null);
-        if (!expectedValue.Equals(val.ToString()))
-        {
-            throw new Exception("Inconsistent Value for key " + key.ToString() + " Expected Value should be " + expectedValue +
-                " but recevied value is " + val.ToString());
-        }
-    }
-    else
-        throw new Exception("Expected Value for key " + key.ToString() + " is not the same type of " + typ);
-}
-
-private void checkUpdatedValue(TKey key, TVal value)
-{
-    ResetKey("versionNum");
-    int versionnum = GetUIntValue("versionNum");
-    Type typ = value.GetType();
-    if (typ == typeof(string))
-    {
-        string expectedStr = "updated_" + key;
-        if (!expectedStr.Equals(value))
-            throw new Exception("Inconsistent Value for key " + key.ToString() + " Expected Value should be " + expectedStr.ToString());
-    }
-    else if (versionnum == 1 && (typ == PdxTests<TKey, TVal>.m_pdxVersionOneAsm.GetType("PdxVersionTests.PdxVersioned")))
-    {
-        string expectedValue = string.Format("PdxVersioned updated_{0}", key);
-        //typ val = (typ.)value;
-        object val = typ.GetProperty("PString").GetValue(value, null);
-        if (!expectedValue.Equals(val.ToString()))
-        {
-            throw new Exception("Inconsistent Value for key " + key.ToString() + " Expected Value should be " + expectedValue +
-                " but recevied value is " + val.ToString());
-        }
-    }
-    else if (versionnum == 2 && (typ == PdxTests<TKey, TVal>.m_pdxVersionTwoAsm.GetType("PdxVersionTests.PdxVersioned")))
-    {
-        string expectedValue = string.Format("PdxVersioned updated_{0}", key);
-        //typ val = (typ.)value;
-        object val = typ.GetProperty("PString").GetValue(value, null);
-        if (!expectedValue.Equals(val.ToString()))
-        {
-            throw new Exception("Inconsistent Value for key " + key.ToString() + " Expected Value should be " + expectedValue +
-                " but recevied value is " + val.ToString());
-        }
-    }
-    else
-    {
-        throw new Exception("Expected Value for key " + key.ToString() + " is not the same type of " + typ);
-    }
-
-}
-      public void DoWaitForSilenceListenerComplete()
-      {
-          int desiredSilenceSec = 30;
-          int sleepMS = 2000;
-          FwkInfo("Waiting for a period of silence for " + desiredSilenceSec + " seconds...");
-          long desiredSilenceMS = desiredSilenceSec * 1000;
-          long silenceStartTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-          long currentTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-          long lastEventTime = (long)Util.BBGet("ListenerBB", "lastEventTime");
-
-          while (currentTime - silenceStartTime < desiredSilenceMS)
-          {
-              try
-              {
-                  Thread.Sleep(sleepMS);
-              }
-              catch (Exception e)
-              {
-                  FwkException("PerfTest::waitForSilence() Caught exception:" + e.Message);
-              }
-              lastEventTime = (long)Util.BBGet("ListenerBB", "lastEventTime");
-              if (lastEventTime > silenceStartTime)
-              {
-                  // restart the wait
-                  silenceStartTime = lastEventTime;
-              }
-              currentTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-          }
-          long duration = currentTime - silenceStartTime;
-          FwkInfo("Done waiting, clients have been silent for " + duration + " ms");
-
-      }
-    //-------------------------------------------------doOps for rvv end-------------
-
-    public static void TestComplete()
-    {
-      OperationsMap.Clear();
-      ExceptionsMap.Clear();
-    }
-
-    #endregion
-  }
-
-  public class Multiusersecurity<TKey, TVal> : FwkTest<TKey, TVal>
-  {
-    #region Private constants and statics
-
-    private static Cache m_cache = null;
-    private const string RegionName = "regionName";
-    private const string ValueSizes = "valueSizes";
-    private const string MultipleUser = "MultiUsers";
-    private const string OpsSecond = "opsSecond";
-    private const string EntryCount = "entryCount";
-    private const string WorkTime = "workTime";
-    private const string EntryOps = "entryOps";
-    private const string isDurable = "isDurable";
-    //private const string MultiUserMode = "multiUserMode";
-    private const string KeyStoreFileProp = "security-keystorepath";
-    private const string KeyStoreAliasProp = "security-alias";
-    private const string KeyStorePasswordProp = "security-keystorepass";
-    private const CredentialGenerator.ClassCode DefaultSecurityCode =
-      CredentialGenerator.ClassCode.LDAP;
-    private static Dictionary<string, IRegion<TKey, TVal>> proxyRegionMap = new Dictionary<string, IRegion<TKey, TVal>>();
-    private static Dictionary<string, IRegionService> authCacheMap = new Dictionary<string, IRegionService>();
-    private static Dictionary<string, Dictionary<string, int>> operationMap=new Dictionary<string,Dictionary<string,int>>();
-    private static Dictionary<string, Dictionary<string, int>> exceptionMap=new Dictionary<string,Dictionary<string,int>>();
-
-    private static ArrayList userList, readerList, queryList, writerList, adminList;  
-    private static Dictionary<string, ArrayList> userToRolesMap=new Dictionary<string,ArrayList>();
-  
-     #endregion
-
-    #region Private utility methods
-
-    public virtual IRegion<TKey,TVal> DoCreateDCRegion()
-    {
-      FwkInfo("In DoCreateDCRegion() Durable");
-
-      ClearCachedKeys();
-
-      string rootRegionData = GetStringValue("regionSpec");
-      string tagName = GetStringValue("TAG");
-      string endpoints = Util.BBGet(JavaServerBB, EndPointTag + tagName)
-        as string;
-      if (rootRegionData != null && rootRegionData.Length > 0)
-      {
-        string rootRegionName;
-        rootRegionName = GetRegionName(rootRegionData);
-        if (rootRegionName != null && rootRegionName.Length > 0)
-        {
-          IRegion<TKey, TVal> region;
-          if ((region = CacheHelper<TKey, TVal>.GetRegion(rootRegionName)) == null)
-          {
-            bool isDC = GetBoolValue("isDurable");
-            string m_isPool = null;
-            // Check if this is a thin-client region; if so set the endpoints
-            int redundancyLevel = 0;
-            if (endpoints != null && endpoints.Length > 0)
-            {
-              redundancyLevel = GetUIntValue(RedundancyLevelKey);
-              if (redundancyLevel < 0)
-                redundancyLevel = 0;
-              string conflateEvents = GetStringValue(ConflateEventsKey);
-              string durableClientId = "";
-              int durableTimeout = 300;
-              if (isDC)
-              {
-                durableTimeout = GetUIntValue("durableTimeout");
-                bool isFeeder = GetBoolValue("isFeeder");
-                if (isFeeder)
-                {
-                  durableClientId = "Feeder";
-                  // VJR: Setting FeederKey because listener cannot read boolean isFeeder
-                  // FeederKey is used later on by Verify task to identify feeder's key in BB
-                  Util.BBSet("DURABLEBB", "FeederKey", "ClientName_" + Util.ClientNum + "_Count");
-                }
-                else
-                {
-                  durableClientId = String.Format("ClientName_{0}", Util.ClientNum);
-                }
-              }
-              FwkInfo("DurableClientID is {0} and DurableTimeout is {1}", durableClientId, durableTimeout);
-              CacheHelper<TKey, TVal>.InitConfigForPoolDurable(durableClientId, durableTimeout, conflateEvents, false);
-              
-
-            }
-            RegionFactory rootAttrs = CacheHelper<TKey, TVal>.DCache.CreateRegionFactory(RegionShortcut.PROXY);
-            SetRegionAttributes(rootAttrs, rootRegionData, ref m_isPool);
-            rootAttrs = CreatePool(rootAttrs, redundancyLevel);
-            FwkInfo("Entering CacheHelper.CreateRegion()");
-            region = CacheHelper<TKey, TVal>.CreateRegion(rootRegionName, rootAttrs);
-            Apache.Geode.Client.RegionAttributes<TKey, TVal> regAttr = region.Attributes;
-            FwkInfo("Region attributes for {0}: {1}", rootRegionName,
-              CacheHelper<TKey, TVal>.RegionAttributesToString(regAttr));
-            if (isDC)
-            {
-              CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-            }
-          }
-          return region;
-        }
-        
-      }
-      else
-      {
-        FwkSevere("DoCreateDCRegion() failed to create region");
-      }
-
-      FwkInfo("DoCreateDCRegion() complete.");
-      return null;
-    }
-
-    public virtual void DoCreateRegion()
-    {
-      FwkInfo("In DoCreateRegion()");
-      try
-      {
-        IRegion<TKey, TVal> region;
-        if (operationMap.Count > 0 || exceptionMap.Count > 0)
-        {
-          operationMap.Clear();
-          exceptionMap.Clear();
-        }
-        ResetKey(isDurable);
-        bool isDC = GetBoolValue(isDurable);
-        if (isDC)
-        {
-          region = DoCreateDCRegion();
-        }
-        else
-        {
-          region = CreateRootRegion();
-        }
-        FwkInfo("The region name is {0}",region.Name);
-
-        if (region != null)
-        {
-          string poolName = region.Attributes.PoolName;
-
-          if (poolName != null)
-          {
-            Pool pool = CacheHelper<TKey, TVal>.DCache.GetPoolManager().Find(poolName);
-            if (pool.MultiuserAuthentication)
-            {
-              FwkInfo("pool is in multiuser mode and entering CreateMultiUserCacheAndRegion");
-              CreateMultiUserCacheAndRegion(pool, region);
-            }
-            else
-              FwkInfo(" pool is not in multiuser mode ");
-          }
-          else
-            FwkInfo("poolName is null ");
-        }
-        else 
-          FwkInfo(" returing null region");
-        //return null;
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreateRegion() complete.");
-    }
-
-    void CreateMultiUserCacheAndRegion(Pool pool,IRegion<TKey,TVal> region) 
-    {
-      FwkInfo("In CreateMultiUserCacheAndRegion()");
-      string userName;
-      CredentialGenerator gen = GetCredentialGenerator();
-      CredentialGenerator.ClassCode SecurityCode = gen.GetClassCode();
-      gen = CredentialGenerator.Create(SecurityCode, true);
-      if (gen == null)
-      {
-        FwkInfo("Skipping security scheme {0} with no generator. Using  default security scheme.{1}", SecurityCode, DefaultSecurityCode);
-        SecurityCode = DefaultSecurityCode;
-      }
-      string scheme = SecurityCode.ToString();
-      string user = GetStringValue(SecurityCode.ToString());
-      string regionName=region.Name;
-      ResetKey(MultipleUser);
-      Int32 numOfMU = GetUIntValue(MultipleUser);
-      userList = new ArrayList();
-     //populating the list with no. of multiusers.
-      for (Int32 i = 1; i <= numOfMU; i++)
-      {
-        string userStr = string.Format("{0}{1}",user,i);
-        userList.Add(userStr);
-      }
-
-      Int32 userSize=userList.Count;
-      if (SecurityCode == CredentialGenerator.ClassCode.LDAP)
-      {
-        for (Int32 i = 0; i < userSize; i++)
-        {
-          Properties<string, string> userProp = new Properties<string, string>();
-          userName = (String)userList[i];
-
-          userProp.Insert("security-username", userName);
-          userProp.Insert("security-password", userName);
-          IRegionService mu_cache = CacheHelper<TKey, TVal>.DCache.CreateAuthenticatedView(CacheHelper<TKey, TVal>.GetPkcsCredentialsForMU(userProp), pool.Name);
-          authCacheMap[userName] = mu_cache;
-          //mu_cache = pool.CreateSecureUserCache(userProp);
-          IRegion<TKey,TVal> m_region = mu_cache.GetRegion<TKey,TVal>(regionName);
-          proxyRegionMap[userName] =  m_region;
-          Dictionary<string, int> opMAP=new Dictionary<string,int>();
-          Dictionary<string, int> expMAP=new Dictionary<string,int>();
-          operationMap[userName] = opMAP;
-          exceptionMap[userName] = expMAP;
-          Utility.GetClientProperties(gen.AuthInit, null, ref userProp);
-          FwkInfo("Security properties entries: {0}", userProp);
-          switch (i)
-          {
-            case 0:
-            case 1:
-              setAdminRole(userName);
-             break;
-            case 2:
-            case 3:
-            case 4:
-              setReaderRole(userName);
-              break;
-            case 5:
-            case 6:
-            case 7:
-              setWriterRole(userName);
-              break;
-            case 8:
-            case 9:
-              setQueryRole(userName);
-              break;
-          };
-        }
-      }
-    }
-
-    public string GetKeyStoreDir(string dataDir)
-    {
-      string keystoreDir = dataDir;
-      if (keystoreDir != null && keystoreDir.Length > 0)
-      {
-        keystoreDir += "/keystore/";
-      }
-      return keystoreDir;
-    }
-
-
-    public void setAdminRole(string userName)
-    {
-      adminList = new ArrayList();
-      adminList.Add("create");
-      adminList.Add("update");
-      adminList.Add("get");
-      adminList.Add("getServerKeys");
-      adminList.Add("destroy");
-      adminList.Add("query");
-      adminList.Add("cq");
-      adminList.Add("putAll");
-      adminList.Add("executefunction");
-      userToRolesMap.Add(userName,adminList);
-    }
-
-    public void setReaderRole(string userName)
-    {
-      readerList = new ArrayList();
-      readerList.Add("get");
-      readerList.Add("getServerKeys");  
-      readerList.Add("cq");
-      userToRolesMap.Add(userName,readerList);
-    }
-
-    public void setWriterRole(string userName)
-    {
-      writerList = new ArrayList();
-      writerList.Add("create");
-      writerList.Add("update");
-      writerList.Add("destroy");
-      writerList.Add("putAll");
-      writerList.Add("executefunction");
-      userToRolesMap.Add(userName, writerList);
-    }
-
-    public void setQueryRole(string userName)
-    {
-      queryList = new ArrayList();
-      queryList.Add("query");
-      queryList.Add("cq");
-      userToRolesMap.Add(userName, queryList);
-    }
-   
-       #region Public methods
-   
-    public void DoFeedTask()
-    {
-      FwkInfo("MultiUserSecurity.DoFeed() called.");
-     
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int cnt = 0;
-      string userName=(String)userList[0];
-      IRegion<TKey,TVal> region= proxyRegionMap[userName];
-      while (cnt++ < entryCount)
-      {
-        string keyStr = cnt.ToString();
-        string value = "Value";
-        TKey key = (TKey)(object)keyStr;
-        TVal val = (TVal)(object)value;
-        region[key] = val;
-      }
-      FwkInfo("MultiUserSecurity.DoFeed() completed");
-    }
-
-    public void DoCqForMU()
-    {
-      FwkInfo("MultiUserSecurity.DoCqForMU() called ");
-      CqQuery<TKey, object> cq;
-      string uName = (String)userList[1];
-      IRegion<TKey,TVal> region = proxyRegionMap[uName];
-      IRegionService authCache = authCacheMap[uName];
-      for (Int32 i = 0; i < userList.Count; i++)
-      {
-        string userName = (String)userList[i];
-        string cqName = String.Format("cq-{0}", userName);
-        var qs = authCache.GetQueryService();
-        CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-        ICqListener<TKey, object> cqLstner = new MyCqListener<TKey, object>();
-        cqFac.AddCqListener(cqLstner);
-        CqAttributes<TKey, object> cqAttr = cqFac.Create();
-        cq = qs.NewCq(cqName, "select * from /Portfolios where TRUE", cqAttr, true);
-        cq.Execute();
-      }
-      FwkInfo("MultiUserSecurity.DoCqForMU() completed");
-    }
-
-    public void DoCloseCacheAndReInitialize() {
-      FwkInfo("MultiUserSecurity.DoCloseCacheAndReInitialize() called");
-      try
-      {
-        //if (mu_cache != null)
-        {
-          IRegion<TKey, TVal>[] vregion = CacheHelper<TKey, TKey>.DCache.RootRegions<TKey, TVal>();
-          try
-          {
-            for (Int32 i = 0; i < vregion.Length; i++)
-            {
-              IRegion<TKey, TVal> region = (IRegion<TKey, TVal>)vregion.GetValue(i);
-              region.GetLocalView().DestroyRegion();
-            }
-          }
-          catch (RegionDestroyedException ignore)
-          {
-            string message = ignore.Message;
-            Util.Log(message);
-          }
-          catch (Exception ex)
-          {
-            FwkException("Caught unexpected exception during region local destroy {0}", ex);
-          }
-          bool keepalive = GetBoolValue("keepAlive");
-          bool isDurable = GetBoolValue("isDurable");
-          if (isDurable)
-          {
-            FwkInfo("KeepAlive is {0}", keepalive);
-            CacheHelper<TKey, TVal>.DCache.Close(keepalive);
-            //m_cache.Close(keepalive);            
-          }
-          else
-            m_cache.Close();
-          m_cache = null;
-          FwkInfo("Cache Close");
-        }
-        proxyRegionMap.Clear();
-        authCacheMap.Clear();
-        operationMap.Clear();
-        exceptionMap.Clear();
-        userToRolesMap.Clear();
-        userList.Clear();
-        CacheHelper<TKey, TVal>.Close();
-          DoCreateRegion();
-        bool isCq = GetBoolValue("cq");
-        if (isCq)
-          DoCqForMU();
-      }
-      catch (CacheClosedException ignore)
-      {
-        string message = ignore.Message;
-        Util.Log(message);
-      }
-      catch (Exception ex)
-      {
-        FwkException("Caught unexpected exception during CacheClose {0}", ex);
-      }
-    }
-
-    public void DoValidateCqOperationsForPerUser() {
-      FwkInfo("MultiUserSecurity.DoValidateCqOperationsForPerUser() called.");
-      try
-      {
-        string uName = (String)userList[0];
-        IRegion<TKey, TVal> region = proxyRegionMap[uName];
-        IRegionService authCache = authCacheMap[uName];
-        var qs = authCache.GetQueryService();
-        ICqListener<TKey, object> cqLstner = new MyCqListener<TKey, object>();
-        for (Int32 i = 0; i < userList.Count; i++)
-        {
-          string userName = (String)userList[i];
-          string cqName = String.Format("cq-{0}", userName);
-          CqQuery<TKey, object> cq = qs.GetCq<TKey, object>(cqName);
-          CqStatistics cqStats = cq.GetStatistics();
-          CqAttributes<TKey, object> cqAttr = cq.GetCqAttributes();
-          ICqListener<TKey, object>[] vl = cqAttr.getCqListeners();
-          cqLstner = vl[0];
-          MyCqListener<TKey, object> myLisner = (MyCqListener<TKey, object>)cqLstner;
-          Util.Log("My count for cq {0} Listener : NumInserts:{1}, NumDestroys:{2}, NumUpdates:{3}, NumEvents:{4}", cq.Name, myLisner.NumInserts(), myLisner.NumDestroys(), myLisner.NumUpdates(), myLisner.NumEvents());
-          Util.Log("Cq {0} from CqStatistics : NumInserts:{1}, NumDestroys:{2}, NumUpdates:{3}, NumEvents:{4} ", cq.Name, cqStats.numInserts(), cqStats.numDeletes(), cqStats.numUpdates(), cqStats.numEvents());
-          if (myLisner.NumInserts() == cqStats.numInserts() && myLisner.NumUpdates() == cqStats.numUpdates() && myLisner.NumDestroys() == cqStats.numDeletes() && myLisner.NumEvents() == cqStats.numEvents())
-            Util.Log("Accumulative event count is correct");
-          else
-            Util.Log("Accumulative event count is incorrect");
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("Query.DoVerifyCQListenerInvoked() Caught Exception : {0}", ex);
-      }
-    }
-
-    public void DoEntryOperationsForMU()
-    {
-      FwkInfo("MultiUserSecurity.DoEntryOperationsForMU() called.");
-      Util.RegisterTestCompleteDelegate(TestComplete);
-      // string bb = "GFE_BB" ;
-     // string ky="scheme" ;
-    //  string securitySch=(String)Util.BBGet(bb,ky);
-      
-      int opsSec = GetUIntValue(OpsSecond);
-      opsSec = (opsSec < 1) ? 0 : opsSec;
-
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-
-      TKey key;
-      TVal value;
-      //ISerializable val;
-
-      CqQuery<TKey, object> cq = null;
-      string opCode = null;
-
-      PaceMeter pm = new PaceMeter(opsSec);
-      while (now < end)
-      {
-        int addOps = 1;
-        Random rdm = new Random();
-        int userSize = userList.Count;
-        string userName = (String)userList[(rdm.Next(userSize))];
-        FwkInfo("The userName is {0}",userName);
-        IRegion<TKey,TVal> region = proxyRegionMap[userName];
-        IRegionService authCache = authCacheMap[userName];
-        opCode = GetStringValue(EntryOps);
-        try
-        {
-          UpdateOperationMap(opCode,userName,1);
-          if (opCode == null || opCode.Length == 0)
-          {
-            opCode = "no-op";
-          }
-
-          if (opCode == "create")
-          {
-            key = (TKey)(object)(rdm.Next(entryCount).ToString());
-            string tempval = "Value";
-            value = (TVal)(object)tempval;
-            region.Add(key, value);
-          }
-          else
-          {
-            key = (TKey)(object)(rdm.Next(entryCount).ToString());
-            if (opCode == "update")
-            {
-              value = (TVal)(object)"Value_";
-              region[key] = value;
-            }
-            else if (opCode == "destroy")
-            {
-              region.Remove(key);
-            }  
-           
-            else if (opCode == "get")
-            {
-                try
-                {
-                   value = region[key];
-                }
-                catch (EntryNotFoundException ex)
-                {
-                    FwkInfo("MultiUser.DoEntryOperationsForMU() Caught non-fatal " +
-                      "ex-ception in read: {0}", ex.Message);
-                }
-                catch (Apache.Geode.Client.KeyNotFoundException ex)
-                {
-                    FwkInfo("MultiUser.DoEntryOperationsForMU() Caught non-fatal " +
-                      "ex-ception in read: {0}", ex.Message);
-                }
-            }
-
-            else if (opCode == "getServerKeys")
-            {
-              ICollection<TKey> serverKeys = region.Keys;
-            }
-             
-            else if (opCode == "query")
-            {
-              var qs = authCache.GetQueryService();
-              Query<object> qry = qs.NewQuery<object>("select distinct * from /Portfolios where FALSE");
-              ISelectResults<object> result = qry.Execute(TimeSpan.FromSeconds(600));
-            }
-            else if (opCode == "cq")
-            {
-              string cqName = String.Format("cq-{0}",userName);
-              var qs = authCache.GetQueryService();
-              CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-              ICqListener<TKey, object> cqLstner = new MyCqListener<TKey, object>();
-              cqFac.AddCqListener(cqLstner);
-              CqAttributes<TKey, object> cqAttr = cqFac.Create();
-              cq = qs.NewCq(cqName, "select * from /Portfolios where FALSE", cqAttr, false);
-              cq.Execute();
-              cq.Stop();
-              cq.Execute();
-              cq.Close();
-            }
-            else if (opCode == "executefunction")
-            {
-              string funcName = null;
-              Random rdn = new Random();
-              int num = rdn.Next(3);
-              Apache.Geode.Client.Execution<object> exc = null;
-              ICollection<object> executeFunctionResult = null;
-              ArrayList args = new ArrayList();
-              Object[] filterObj = new Object[1];
-              filterObj[0] = rdm.Next(entryCount).ToString();
-              //args.Add(filterObj[0]);
-              Util.Log("Inside FE num = {0}",num);
-              if (num == 0)
-              {
-                args.Add(filterObj[0]);
-                args.Add("addKey"); 
-                funcName = "RegionOperationsFunction";
-                exc = Client.FunctionService<object>.OnRegion(region);
-                executeFunctionResult = exc.WithArgs(args).WithFilter(filterObj).Execute(funcName, TimeSpan.FromSeconds(15)).GetResult();
-              }
-              else if (num == 1)
-              {
-                args.Add(filterObj[0]);
-                funcName = "ServerOperationsFunction";
-                //exc = region.Cache.GetFunctionService().OnServer();
-                exc = Client.FunctionService<object>.OnServer(authCache);
-                executeFunctionResult = exc.WithArgs(args).Execute(funcName, TimeSpan.FromSeconds(15)).GetResult();
-              }
-              else
-              {
-                try
-                {
-                  args.Add(filterObj[0]);
-                  funcName = "ServerOperationsFunction";
-                  //exc = region.Cache.GetFunctionService().OnServers();
-                  exc = Client.FunctionService<object>.OnServers(authCache);
-                  executeFunctionResult = exc.WithArgs(args).Execute(funcName, TimeSpan.FromSeconds(15)).GetResult();
-                }
-                catch (FunctionExecutionException)
-                {
-                  //expected exception
-                  Util.Log("Inside FunctionExecutionException");
-                }
-              }
-            }
-            else if (opCode == "putAll")
-            {
-              IDictionary<TKey, TVal> map = new Dictionary<TKey, TVal>();
-              for (int count = 0; count < 200; count++)
-              {
-                key = (TKey)(object)count.ToString();
-                value = (TVal)(object)"Value_";
-                map.Add(key, value);
-              }
-              region.PutAll(map);
-            }
-            else
-            {
-              FwkException("CacheServer.DoEntryOperationsForSecurity() " +
-                "Invalid operation specified: {0}", opCode);
-            }
-          }
-        }
-        catch (NotAuthorizedException ex)
-        {
-         
-          FwkInfo("Got expected NotAuthorizedException for operation {0}: {1}",
-            opCode, ex.Message);
-          if (opCode == "cq")
-          {
-            if (cq.IsStopped())
-              cq.Close();
-          }
-          UpdateExceptionMap(opCode,userName,1);
-        }
-        catch (EntryExistsException)
-        {
-          addOps = -1;
-          
-       UpdateOperationMap(opCode,userName,addOps);
-        }
-        catch (EntryNotFoundException)
-        {
-          addOps = -1;
-        UpdateExceptionMap(opCode,userName,addOps);
-        }
-        catch (EntryDestroyedException)
-        {
-          addOps = -1;
-          UpdateExceptionMap(opCode, userName, addOps);
-        }
-        catch (CqExistsException)
-        {
-          Util.Log("Inside CqExistsException ");
-        }
-        catch (TimeoutException ex)
-        {
-          FwkSevere("Caught unexpected timeout exception during entry {0} " +
-            " operation: {1}; continuing with test.", opCode, ex.Message);
-        }
-        catch (Exception ex)
-        {
-          FwkException("MultiUserSecurity.DoEntryOperationsForSecurity() Caught " +
-            "unexpected exception during entry '{0}' operation: {1}.",
-            opCode, ex);
-        }
-        pm.CheckPace();
-        now = DateTime.Now;
-      }
-      key = default(TKey);
-      value = default(TVal);
-      FwkInfo("MultiUserSecurity.DoEntryOperationsForSecurity() complete");
-    }
-
-    public void UpdateOperationMap(string opcode, string userName,int numOps)
-    {
-      FwkInfo("Inside updateOperationMap");
-      lock (((IDictionary)operationMap).SyncRoot)
-      {
-        Dictionary<string, int> opMap = operationMap[userName];
-        int currentOps;
-        if (!opMap.TryGetValue(opcode, out currentOps))
-        {
-          currentOps = 0;
-        }
-        opMap[opcode] = currentOps + numOps;
-        operationMap[userName] = opMap;
-      }
-    }
-
-    public void UpdateExceptionMap(string opcode, string userName, int numOps)
-    {
-      lock (((IDictionary)operationMap).SyncRoot)
-
-      {
-        Dictionary<string, int> expMap = exceptionMap[userName];
-        int currentOps;
-        if (!expMap.TryGetValue(opcode, out currentOps))
-        {
-          currentOps = 0;
-        }
-        expMap[opcode] = currentOps + numOps;
-        exceptionMap[userName]=expMap;
-      }
-    }
-    public int GetOpsFromMap(Dictionary<string, int> map, string opCode)
-    {
-      int numOps;
-      lock (((ICollection)map).SyncRoot)
-      {
-        if (!map.TryGetValue(opCode, out numOps))
-        {
-          numOps = 0;
-        }
-      }
-      return numOps;
-    }
-
-    public void DoValidateEntryOperationsForPerUser()
-    {
-      FwkInfo("Multiusersecurity.DoValidateEntryOperationsForPerUser() started");
-      bool opFound = false;
-      for (int i = 0; i < userList.Count; i++)
-      {
-        Dictionary<string, int> validateOpMap;
-        Dictionary<string, int> validateExpMap;
-        string userName = (String)userList[i];
-        validateOpMap = operationMap[userName];
-        validateExpMap = exceptionMap[userName];
-        foreach (string opcode in validateOpMap.Keys) 
-        {
-          FwkInfo("opcode is {0} for user {1}", opcode,userName);
-          int totalOpCnt = GetOpsFromMap(validateOpMap,opcode);
-          int totalNotAuthCnt = GetOpsFromMap(validateExpMap, opcode);
-          ArrayList roleList = new ArrayList();
-          roleList = userToRolesMap[userName];
-          for (int j = 0; j < roleList.Count; j++)
-          {
-            if ((String)roleList[j] == opcode)
-            {
-              opFound = true;
-              break;
-            }
-            else
-              opFound = false;
-          }
-          if (opFound)
-          {
-            if ((totalOpCnt != 0) && (totalNotAuthCnt == 0))
-            {
-              FwkInfo("Task passed sucessfully with total operation = {0} for user {1}", totalOpCnt, userName);
-            }
-            else
-            {
-              FwkException("Task failed for user {0} NotAuthorizedException found for operation = {1} while expected was 0", userName, totalNotAuthCnt);
-            }
-          }
-          else
-          {
-            if (totalOpCnt == totalNotAuthCnt)
-            {
-              FwkInfo("Task passed sucessfully and got the expected number of notAuth exception = {0} with total number of operation = {1}", totalOpCnt, totalNotAuthCnt);
-            }
-            else
-            {
-              FwkException("Task failed ,Expected NotAuthorizedException cnt to be = {0} but found = {1}",totalOpCnt,totalNotAuthCnt);
-            }
-          }
-        }
-      }
-    }
-
-    public void DoCloseCache()
-    {
-      FwkInfo("DoCloseCache()  Closing cache and disconnecting from" +
-        " distributed system.");
-      userToRolesMap.Clear();
-      proxyRegionMap.Clear();
-      authCacheMap.Clear();
-      CacheHelper<TKey,TVal>.Close();
-    }
-    public static void TestComplete()
-    {
-      operationMap.Clear();
-      exceptionMap.Clear();
-    }
-
-    #endregion
- 
-  }
-   #endregion
- 
-}
-
diff --git a/tests/cli/NewFwkLib/DeltaTest/DeltaClientValidationListener.cs b/tests/cli/NewFwkLib/DeltaTest/DeltaClientValidationListener.cs
deleted file mode 100644
index 87b591c..0000000
--- a/tests/cli/NewFwkLib/DeltaTest/DeltaClientValidationListener.cs
+++ /dev/null
@@ -1,190 +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.
- */
-
-using System;
-using System.Threading;
-using System.Collections.Generic;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-  public class DeltaClientValidationListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>
-  {
-    private IDictionary<TKey, Int32> m_latestValues;
-    private IDictionary<TKey, Int64> m_ValidateMap;
-    private long m_numAfterCreate;
-    private long m_numAfterUpdate;
-    private long m_numAfterInvalidate;
-    private long m_numAfterDestroy;
-    
-    public DeltaClientValidationListener()
-    {
-      m_numAfterCreate = 0;
-      m_numAfterUpdate = 0;
-      m_numAfterInvalidate = 0;
-      m_numAfterDestroy = 0;
-      m_latestValues = new Dictionary<TKey, Int32>();
-      m_ValidateMap = new Dictionary<TKey, Int64>();
-    }
-
-    public static ICacheListener<TKey, TVal> Create()
-    {
-      return new DeltaClientValidationListener<TKey, TVal>();
-    }
-    ~DeltaClientValidationListener() { }
-
-    #region ICacheListener Members
-
-    public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-      m_numAfterCreate++;
-      TKey key = (TKey)ev.Key;
-      DeltaTestImpl value = ev.NewValue as DeltaTestImpl;
-      if (value == null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException(" Value in afterCreate cannot be null : key = {0} ", key.ToString());
-        return;
-      }
-      if( value.GetIntVar() != 0 && value.GetFromDeltaCounter() != 0)
-      {
-         ValidateIncreamentByOne(key,value);
-      }
-      Int32 mapValue = value.GetIntVar();
-      Int64 deltaValue = value.GetFromDeltaCounter();
-      m_latestValues[key] = mapValue;
-      m_ValidateMap[key] = deltaValue;
-    }
-
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      m_numAfterUpdate++;
-      TKey key = ev.Key;
-      DeltaTestImpl oldValue = ev.OldValue as DeltaTestImpl;
-      DeltaTestImpl newValue = ev.NewValue as DeltaTestImpl;
-      if (newValue == null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException(" newValue in afterUpdate cannot be null : key = {0} ", key.ToString());
-        return;
-      }
-       if (oldValue == null)
-        {
-          ValidateIncreamentByOne(key, newValue);
-        }
-        else
-        {
-          Int32 mapValue1;
-          m_latestValues.TryGetValue(key, out mapValue1);
-          Int32 mapValue2 = mapValue1;
-          // CacheableInt32 mapValue2 = m_latestValues[key] as CacheableInt32;
-          Int32 diff = newValue.GetIntVar() - mapValue2;
-          if (diff != 1)
-          {
-            FwkTest<TKey, TVal>.CurrentTest.FwkException("difference expected in newValue and oldValue is 1 , but it was not" +
-              " for key {0} & newVal = {1} oldValue = {2} map count = {3} : {4}", key.ToString(), newValue.GetIntVar(), mapValue2, m_latestValues.Count, m_latestValues.ToString());
-            return;
-          }
-        }
-        Int32 mapValue = newValue.GetIntVar();
-        Int64 deltaValue = newValue.GetFromDeltaCounter();
-        m_latestValues[key] = mapValue;
-        m_ValidateMap[key] = deltaValue;
-    }
-
-    public override void AfterRegionLive(RegionEvent<TKey, TVal> ev) 
-    {
-    }
-
-    public override void AfterDestroy(EntryEvent<TKey, TVal> ev)
-    {
-      m_numAfterDestroy++;
-      TKey key = ev.Key;
-      DeltaTestImpl oldValue=ev.OldValue as DeltaTestImpl;
-      if (oldValue != null)
-      {
-        Int32 mapValue = oldValue.GetIntVar();
-        m_latestValues.Remove(key);
-        //m_ValidateMap.Remove(key);
-      }
-    }
-
-    public override void AfterInvalidate(EntryEvent<TKey, TVal> ev)
-    {
-      m_numAfterInvalidate++;
-      TKey key = ev.Key;
-      DeltaTestImpl oldValue = ev.OldValue as DeltaTestImpl;
-      if(oldValue==null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException("oldValue cannot be null key = {0}", key.ToString());
-        return;
-      }
-      Int32 mapValue = oldValue.GetIntVar();
-      m_latestValues[key] = 0;
-      
-    }
-
-    public override void AfterRegionDestroy(RegionEvent<TKey, TVal> ev)
-    {
-      dumbToBB(ev.Region);
-    }
-
-    public override void AfterRegionInvalidate(RegionEvent<TKey, TVal> ev)
-    {
-    }
-
-    public override void Close(Apache.Geode.Client.IRegion<TKey, TVal> region)
-    {
-    }
-
-    public override void AfterRegionDisconnected(Apache.Geode.Client.IRegion<TKey, TVal> region)
-    {
-    }
-    public override void AfterRegionClear(RegionEvent<TKey, TVal> ev)
-    {
-      // Do nothing.
-    }
-
-    public IDictionary<TKey, Int64> getMap() 
-    {
-      return m_ValidateMap;
-    }
-    private void dumbToBB(IRegion<TKey, TVal> region)
-    {
-      Util.BBSet("DeltaBB", "AFTER_CREATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterCreate);
-      Util.BBSet("DeltaBB", "AFTER_UPDATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterUpdate);
-      Util.BBSet("DeltaBB", "AFTER_INVALIDATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterInvalidate);
-      Util.BBSet("DeltaBB", "AFTER_DESTROY_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterDestroy);
-    }
-
-    public void ValidateIncreamentByOne(TKey key, DeltaTestImpl newValue)
-    {
-      Int32 oldValue =  m_latestValues[key];
-      if (oldValue == 0)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException("oldValue in latestValues cannot be null: key = {0} & newVal = {1} ", key, newValue.ToString());
-      }
-      Int32 diff = newValue.GetIntVar() - oldValue;
-      if (diff != 1)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException("defference expected in newValue and oldValue is 1 , but it was {0}" +
-          " for key {1} & newVal = {2}", diff, key, newValue.ToString());
-      }
-    } 
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/DeltaTest/DeltaTest.cs b/tests/cli/NewFwkLib/DeltaTest/DeltaTest.cs
deleted file mode 100644
index e3fc098..0000000
--- a/tests/cli/NewFwkLib/DeltaTest/DeltaTest.cs
+++ /dev/null
@@ -1,749 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-using System.Xml.Serialization;
-using Apache.Geode.Client.Tests;
-
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-  public class PutTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private int m_MaxKeys;
-    private List<IDictionary<TKey, TVal>> m_maps;
-    private Int32 m_update;
-    private Int32 m_cnt;
-    private bool m_isCreate;
-    
-    #endregion
-
-    public PutTask(IRegion<TKey, TVal> region, int keyCnt, List<IDictionary<TKey, TVal>> maps, bool isCreate)
-      : base()
-    {
-      m_region = region;
-      m_MaxKeys = keyCnt;
-      m_maps = maps;
-      m_update = 0;
-      m_cnt = 0;
-      m_isCreate = isCreate;
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("PutTask::DoTask:");
-      Int32 localcnt = m_cnt;
-      Interlocked.Increment(ref m_cnt);
-      int offset = Util.Rand(m_MaxKeys);
-      int count = offset;
-      while (Running && (iters-- != 0))
-      {
-        int idx = count % m_MaxKeys;
-        TKey key = default(TKey);
-        try
-        {
-          key = (TKey)(object)("AAAAAA" + localcnt + idx.ToString("D10"));
-          DeltaTestImpl oldVal = (m_maps[localcnt])[key] as DeltaTestImpl;
-          if (oldVal == null)
-          {
-            Util.Log(Util.LogLevel.Error, "oldDelta Cannot be null");
-          }
-          DeltaTestImpl obj = new DeltaTestImpl(oldVal);
-          obj.SetIntVar(oldVal.GetIntVar() + 1);
-          m_region[key] = (TVal)(object)obj;
-          Interlocked.Increment(ref m_update);
-          Util.BBSet("ToDeltaBB", key.ToString(), oldVal.GetToDeltaCounter());
-          bool removeKey = (m_maps[localcnt]).Remove(key);
-          if (removeKey)
-          {
-            (m_maps[localcnt]).Add(key, (TVal)(object)obj);
-          }
-        }
-        catch (Exception ex)
-        {
-          Util.Log(Util.LogLevel.Error,
-            "Exception while putting key[{0}] for region {1} in iteration " +
-            "{2}: {3}", key, m_region.Name, (count - offset), ex);
-          throw;
-        }
-        count++;
-        //if ((count % 1000) == 0)
-        //{
-        //  Util.Log("PutsTask::DoTask: Intermediate: Ran for 1000 iterations.");
-        //}
-      }
-      //Util.Log("PutsTask::DoTask: Ran for {0} iterations.", count);
-      Interlocked.Add(ref m_iters, count - offset);
-    }
-    public void dumpToBB()
-    {
-      Int32 localcnt = m_cnt;
-      Int32 size = m_maps.Count;
-      Int32 count = 0;
-      Int32 i = 0;
-      while (i < size)
-      {
-        count += m_maps[i].Count;
-        foreach (KeyValuePair<TKey, TVal> item in m_maps[i])
-        {
-          TKey key = (TKey)(object)item.Key;
-          DeltaTestImpl value = item.Value as DeltaTestImpl; ;
-          Util.BBSet("ToDeltaBB", key.ToString(), value.GetToDeltaCounter());
-        }
-        i++;
-      }
-      Util.BBSet("MapCount", "size", count);
-      Util.BBSet("DeltaBB", "UPDATECOUNT", m_update);
-    }
-  }
-
-  public class CreateTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private int m_MaxKeys;
-    private List<IDictionary<TKey, TVal>> m_maps;
-    private Int32 m_create;
-    private Int32 m_cnt;
-
-
-    #endregion
-
-    public CreateTask(IRegion<TKey, TVal> region, int keyCnt, List<IDictionary<TKey, TVal>> maps)
-      : base()
-    {
-      m_region = region;
-      m_MaxKeys = keyCnt;
-      m_maps = maps;
-      m_create = 0;
-      m_cnt = 0;
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      Int32 localcnt = m_cnt;
-      Interlocked.Increment(ref m_cnt);
-      IDictionary<TKey, TVal> hmoc = new Dictionary<TKey, TVal>();
-      lock (m_maps)
-      {
-        m_maps.Add(hmoc);
-      }
-      int offset = Util.Rand(m_MaxKeys);
-      int count = offset;
-      Util.Log("CreateTask::DoTask: starting {0} iterations.", iters);
-      while (Running && (iters-- != 0))
-      {
-        int idx = count % m_MaxKeys;
-        TKey key = default(TKey);
-        try
-        {
-          key = (TKey)(object)("AAAAAA" + localcnt + idx.ToString("D10"));
-          TVal obj = (TVal)(object)(new DeltaTestImpl(0, "delta"));
-          m_region.Add(key, obj);
-          Interlocked.Increment(ref m_create);
-          (m_maps[localcnt]).Add(key, obj);
-        }
-        catch (Exception ex)
-        {
-          Util.Log(Util.LogLevel.Error,
-            "Exception while creating key[{0}] for region {1} in iteration " +
-            "{2}: {3}", key, m_region.Name, (count - offset), ex);
-          throw;
-        }
-        count++;
-      }
-      Interlocked.Add(ref m_iters, count - offset);
-    }
-    public void dumpToBB()
-    {
-      Util.BBSet("DeltaBB", "CREATECOUNT", m_create);
-      Util.BBSet("DeltaBB", "DESTROYCOUNT", 0);
-    }
-  }
-
-  public class EntryTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private int m_MaxKeys;
-    private List<IDictionary<TKey, TVal>> m_maps;
-    private Int32 m_create;
-    private Int32 m_update;
-    private Int32 m_destroy;
-    private Int32 m_invalidate;
-    private Int32 m_cnt;
-    bool m_isDestroy;
-    private object CLASS_LOCK = new object();
-    
-    #endregion
-
-    public EntryTask(IRegion<TKey, TVal> region, int keyCnt, List<IDictionary<TKey, TVal>> maps)
-      : base()
-    {
-      m_region = region;
-      m_MaxKeys = keyCnt;
-      m_maps = maps;
-      m_create = 0;
-      m_update = 0;
-      m_destroy = 0;
-      m_invalidate = 0;
-      m_cnt = 0;
-      m_isDestroy = true;
-    }
-
-    DeltaTestImpl getLatestDelta(TKey key, Int32 localcnt, bool isCreate)
-    {
-      DeltaTestImpl oldValue = (m_maps[localcnt])[key] as DeltaTestImpl;
-      if (oldValue == null)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("oldDelta cannot be null");
-      }
-      DeltaTestImpl obj = new DeltaTestImpl(oldValue.GetIntVar() + 1, "delta");
-      if (!isCreate)
-      {
-        obj.SetIntVar(oldValue.GetIntVar() + 1);
-      }
-      return obj;
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      Int32 localcnt = m_cnt;
-      Interlocked.Increment(ref m_cnt);
-      IDictionary<TKey, TVal> hmoc = new Dictionary<TKey, TVal>();
-      lock (m_maps)
-      {
-        m_maps.Add(hmoc);
-      }
-      int offset = Util.Rand(m_MaxKeys);
-      int count = offset;
-      TKey key = default(TKey);
-      Util.Log("EntryTask::DoTask: starting {0} iterations.", iters);
-      while (Running && (iters-- != 0))
-      {
-        int idx = count % m_MaxKeys;
-        key = (TKey)(object)("AAAAAA" + localcnt + idx.ToString("D10"));
-        string opcode = FwkTest<TKey, TVal>.CurrentTest.GetStringValue("entryOps");
-        if (opcode == null) opcode = "no-opcode";
-        if (opcode == "put")
-        {
-          lock (CLASS_LOCK)
-          {
-            DeltaTestImpl newValue = null;
-            if (m_region.ContainsKey(key))
-            {
-              DeltaTestImpl oldValue = m_region[key] as DeltaTestImpl;
-              if (oldValue == null)
-              {
-                newValue = getLatestDelta(key, localcnt, false);
-                m_region[key] = (TVal)(object)newValue;
-              }
-              else
-              {
-                newValue = new DeltaTestImpl(oldValue);
-                newValue.SetIntVar(oldValue.GetIntVar() + 1);
-                m_region[key] = (TVal)(object)newValue;
-              }
-              Interlocked.Increment(ref m_update);
-              //Util.BBSet("ToDeltaBB", key.ToString(), newValue.GetToDeltaCounter());
-            }
-            else
-            {
-              newValue = getLatestDelta(key, localcnt, true);
-              m_region.Add(key, (TVal)(object)newValue);
-              Interlocked.Increment(ref m_create);
-            }
-            //(m_maps[localcnt]).Add(key, newValue);
-            m_maps[localcnt][key] = (TVal)(object)newValue;
-          }
-        }
-        else if (opcode == "destroy")
-        {
-          DeltaTestImpl oldValue = null;
-          if (m_region.ContainsKey(key))
-          {
-            if ((oldValue = m_region[key] as DeltaTestImpl) == null)
-            {
-              if (m_isDestroy)
-              {
-                 m_region.Remove(key);
-                (m_maps[localcnt]).Remove(key);
-              }
-            }
-            else
-            {
-              m_maps[localcnt][key] = (TVal)(object)oldValue;
-              m_region.Remove(key);
-              //(m_maps[localcnt]).Remove(key);
-            }
-            Interlocked.Increment(ref m_destroy);
-           } 
-        }
-        else if (opcode == "invalidate")
-        {
-          DeltaTestImpl oldValue = null;
-          if (m_region.ContainsKey(key))
-          {
-            if ((oldValue = m_region[key] as DeltaTestImpl) != null)
-            {
-              m_maps[localcnt].Add(key, (TVal)(object)oldValue);
-              m_region.Invalidate(key);
-              Interlocked.Increment(ref m_invalidate);
-              m_maps[localcnt].Add(key, default(TVal));
-            }
-          }
-        }
-      }
-      Interlocked.Add(ref m_iters, count - offset);
-    }
-
-    public void dumpToBB()
-    {
-      Int32 localcnt = m_cnt;
-      Int32 size = m_maps.Count;
-      Int32 count = 0;
-      Int32 i = 0;
-      while(i < size)
-      {
-        count += m_maps[i].Count;
-        foreach (KeyValuePair<TKey, TVal> item in m_maps[i])
-        {
-          TKey key = (TKey)(object)item.Key;
-          DeltaTestImpl value = item.Value as DeltaTestImpl;
-          Util.BBSet("ToDeltaBB", key.ToString(), value.GetToDeltaCounter());
-         }
-         i++;
-      }
-      Util.BBSet("MapCount", "size", count);
-      Int32 createCnt = (Int32)Util.BBGet("DeltaBB", "CREATECOUNT");
-      Util.BBSet("DeltaBB", "CREATECOUNT", createCnt + m_create);
-      Util.BBSet("DeltaBB", "UPDATECOUNT", m_update);
-      Util.BBSet("DeltaBB", "DESTROYCOUNT", m_destroy);
-    }
-
-  }
-
-  public class DeltaTest<TKey, TVal> : FwkTest<TKey, TVal>
-  {
-    protected TKey[] m_keysA;
-    protected int m_maxKeys;
-    protected int m_keyIndexBegin;
-
-    protected TVal[] m_cValues;
-    protected int m_maxValues;
-
-    protected const string ClientCount = "clientCount";
-    protected const string TimedInterval = "timedInterval";
-    protected const string DistinctKeys = "distinctKeys";
-    protected const string NumThreads = "numThreads";
-    protected const string ValueSizes = "valueSizes";
-    protected const string OpsSecond = "opsSecond";
-    protected const string KeyType = "keyType";
-    protected const string KeySize = "keySize";
-    protected const string KeyIndexBegin = "keyIndexBegin";
-    protected const string RegisterKeys = "registerKeys";
-    protected const string RegisterRegex = "registerRegex";
-    protected const string UnregisterRegex = "unregisterRegex";
-    protected const string ExpectedCount = "expectedCount";
-    protected const string InterestPercent = "interestPercent";
-    protected const string KeyStart = "keyStart";
-    protected const string KeyEnd = "keyEnd";
-    protected char m_keyType = 'i';
-    protected static List<IDictionary<TKey, TVal>> mapList = new List<IDictionary<TKey, TVal>>();
-    private static bool isObjectRegistered = false;
-
-
-    protected void ClearKeys()
-    {
-      if (m_keysA != null)
-      {
-        for (int i = 0; i < m_keysA.Length; i++)
-        {
-          if (m_keysA[i] != null)
-          {
-            //m_keysA[i].Dispose();
-            m_keysA[i] = default(TKey);
-          }
-        }
-        m_keysA = null;
-        m_maxKeys = 0;
-      }
-    }
-
-    protected int InitKeys(bool useDefault)
-    {
-      string typ = GetStringValue(KeyType); // int is only value to use
-      char newType = (typ == null || typ.Length == 0) ? 's' : typ[0];
-
-      int low = GetUIntValue(KeyIndexBegin);
-      low = (low > 0) ? low : 0;
-      int numKeys = GetUIntValue(DistinctKeys);  // check distinct keys first
-      if (numKeys <= 0)
-      {
-        if (useDefault)
-        {
-          numKeys = 5000;
-        }
-        else
-        {
-          //FwkSevere("Failed to initialize keys with numKeys: {0}", numKeys);
-          return numKeys;
-        }
-      }
-      int high = numKeys + low;
-      FwkInfo("InitKeys:: numKeys: {0}; low: {1}", numKeys, low);
-      if ((newType == m_keyType) && (numKeys == m_maxKeys) &&
-        (m_keyIndexBegin == low))
-      {
-        return numKeys;
-      }
-
-      ClearKeys();
-      m_maxKeys = numKeys;
-      m_keyIndexBegin = low;
-      m_keyType = newType;
-      if (m_keyType == 'i')
-      {
-        InitIntKeys(low, high);
-      }
-      else
-      {
-        int keySize = GetUIntValue(KeySize);
-        keySize = (keySize > 0) ? keySize : 10;
-        string keyBase = new string('A', keySize);
-        InitStrKeys(low, high, keyBase);
-      }
-      for (int j = 0; j < numKeys; j++)
-      {
-        int randIndx = Util.Rand(numKeys);
-        if (randIndx != j)
-        {
-          TKey tmp = m_keysA[j];
-          m_keysA[j] = m_keysA[randIndx];
-          m_keysA[randIndx] = tmp;
-        }
-      }
-      return m_maxKeys;
-    }
-
-    protected int InitKeys()
-    {
-      return InitKeys(true);
-    }
-
-    protected void InitStrKeys(int low, int high, string keyBase)
-    {
-      m_keysA = (TKey[])(object)new String[m_maxKeys];
-      FwkInfo("m_maxKeys: {0}; low: {1}; high: {2}",
-        m_maxKeys, low, high);
-      for (int i = low; i < high; i++)
-      {
-        m_keysA[i - low] = (TKey)(object)(keyBase + i.ToString("D10"));
-      }
-    }
-
-    protected void InitIntKeys(int low, int high)
-    {
-      m_keysA = (TKey[])(object)new Int32[m_maxKeys];
-      FwkInfo("m_maxKeys: {0}; low: {1}; high: {2}",
-        m_maxKeys, low, high);
-      for (int i = low; i < high; i++)
-      {
-        m_keysA[i - low] = (TKey)(object)i;
-      }
-    }
-    protected IRegion<TKey,TVal> GetRegion()
-    {
-      return GetRegion(null);
-    }
-
-    protected IRegion<TKey, TVal> GetRegion(string regionName)
-    {
-      IRegion<TKey, TVal> region;
-      if (regionName == null)
-      {
-        region = GetRootRegion();
-        if (region == null)
-        {
-          IRegion<TKey, TVal>[] rootRegions = CacheHelper<TKey, TVal>.DCache.RootRegions<TKey, TVal>();
-          if (rootRegions != null && rootRegions.Length > 0)
-          {
-            region = rootRegions[Util.Rand(rootRegions.Length)];
-          }
-        }
-      }
-      else
-      {
-        region = CacheHelper<TKey, TVal>.GetRegion(regionName);
-      }
-      return region;
-    }
-    public DeltaTest()
-    {
-      //FwkInfo("In DeltaTest()");
-    }
-    public static ICacheListener<TKey, TVal> CreateDeltaValidationCacheListener()
-    {
-      return new DeltaClientValidationListener<TKey, TVal>();
-    }
-
-   public virtual void DoCreateRegion()
-    {
-      FwkInfo("In DoCreateRegion()");
-      try
-      {
-        if (!isObjectRegistered)
-        {
-
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterType(DeltaTestImpl.CreateDeserializable, 0x1E);
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterType(TestObject1.CreateDeserializable, 0x1F);
-          isObjectRegistered = true;
-        }
-          IRegion<TKey, TVal> region = CreateRootRegion();
-          if (region == null)
-          {
-            FwkException("DoCreateRegion()  could not create region.");
-          }
-          FwkInfo("DoCreateRegion()  Created region '{0}'", region.Name);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreateRegion() complete.");
-    }
-
-    public virtual void DoCreatePool()
-    {
-      FwkInfo("In DoCreatePool()");
-      try
-      {
-        CreatePool();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreatePool() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreatePool() complete.");
-    }
-
-    public void DoRegisterAllKeys()
-    {
-      FwkInfo("In DoRegisterAllKeys()");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        FwkInfo("DoRegisterAllKeys() region name is {0}", region.Name);
-        bool isDurable = GetBoolValue("isDurableReg");
-        ResetKey("getInitialValues");
-        bool isGetInitialValues = GetBoolValue("getInitialValues");
-        region.GetSubscriptionService().RegisterAllKeys(isDurable, isGetInitialValues);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRegisterAllKeys() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRegisterAllKeys() complete.");
-    }
-    public void DoPuts()
-    {
-      FwkInfo("In DoPuts()");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        int numClients = GetUIntValue(ClientCount);
-        string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        int timedInterval = GetTimeValue(TimedInterval) * 1000;
-        if (timedInterval <= 0)
-        {
-          timedInterval = 5000;
-        }
-        int maxTime = 10 * timedInterval;
-
-        // Loop over key set sizes
-        ResetKey(DistinctKeys);
-        int numKeys;
-        while ((numKeys = InitKeys(false)) > 0)
-        { // keys loop
-          // Loop over value sizes
-
-          ResetKey(NumThreads);
-          int numThreads;
-          while ((numThreads = GetUIntValue(NumThreads)) > 0)
-          {
-            PutTask<TKey, TVal> puts = new PutTask<TKey, TVal>(region, numKeys / numThreads, mapList, true);
-            FwkInfo("Running timed task ");
-            try
-            {
-              RunTask(puts, numThreads, -1, timedInterval, maxTime, null);
-            }
-            catch (ClientTimeoutException)
-            {
-              FwkException("In DoPuts()  Timed run timed out.");
-            }
-            puts.dumpToBB();
-            Thread.Sleep(3000); // Put a marker of inactivity in the stats
-          }
-          Thread.Sleep(3000); // Put a marker of inactivity in the stats
-        } // keys loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPuts() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000); // Put a marker of inactivity in the stats
-      FwkInfo("DoPuts() complete.");
-    }
-
-    public void DoPopulateRegion()
-    {
-      FwkInfo("In DoPopulateRegion()");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        int numKeys = InitKeys();
-        ResetKey(NumThreads);
-        int numThreads = GetUIntValue(NumThreads);
-        CreateTask<TKey, TVal> creates = new CreateTask<TKey, TVal>(region, (numKeys / numThreads), mapList);
-        FwkInfo("Populating region.");
-        RunTask(creates, numThreads, (numKeys / numThreads), -1, -1, null);
-        creates.dumpToBB();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPopulateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoPopulateRegion() complete.");
-    }
-
-    public void DoEntryOperation()
-    {
-      FwkInfo("In DoEntryOperation");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        int numClients = GetUIntValue(ClientCount);
-        string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        int timedInterval = GetTimeValue(TimedInterval) * 1000;
-        {
-          timedInterval = 5000;
-        }
-        int maxTime = 10 * timedInterval;
-
-        // Loop over key set sizes
-        ResetKey(DistinctKeys);
-        int numKeys = GetUIntValue(DistinctKeys);
-        ResetKey(NumThreads);
-        int numThreads;
-        while ((numThreads = GetUIntValue(NumThreads)) > 0)
-        {
-          EntryTask<TKey, TVal> entrytask = new EntryTask<TKey, TVal>(region, numKeys / numThreads, mapList);
-          FwkInfo("Running timed task ");
-          try
-          {
-            RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-          }
-          catch (ClientTimeoutException)
-          {
-            FwkException("In DoPuts()  Timed run timed out.");
-          }
-          Thread.Sleep(3000);
-          entrytask.dumpToBB();
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoEntryOperation() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoEntryOperation() complete.");
-    }
-
-    public void DoCloseCache()
-    {
-      FwkInfo("DoCloseCache()  Closing cache and disconnecting from" +
-        " distributed system.");
-      CacheHelper<TKey, TVal>.Close();
-    }
-    public void DoValidateDeltaTest()
-    {
-      FwkInfo("DoValidateDeltaTest() called.");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        region.GetLocalView().DestroyRegion();
-        TKey key = default(TKey);
-        Int32 expectedAfterCreateEvent = (Int32)Util.BBGet("DeltaBB", "CREATECOUNT");
-        Int32 expectedAfterUpdateEvent = (Int32)Util.BBGet("DeltaBB", "UPDATECOUNT");
-        Int32 expectedAfterDestroyEvent = (Int32)Util.BBGet("DeltaBB", "DESTROYCOUNT");
-        long eventAfterCreate = (long)Util.BBGet("DeltaBB", "AFTER_CREATE_COUNT_" + Util.ClientId + "_" + region.Name);
-        long eventAfterUpdate = (long)Util.BBGet("DeltaBB", "AFTER_UPDATE_COUNT_" + Util.ClientId + "_" + region.Name);
-        long eventAfterDestroy = (long)Util.BBGet("DeltaBB", "AFTER_DESTROY_COUNT_" + Util.ClientId + "_" + region.Name);
-        FwkInfo("DoValidateDeltaTest() -- eventAfterCreate {0} ,eventAfterUpdate {1} ,eventAfterDestroy {2}", eventAfterCreate, eventAfterUpdate, eventAfterDestroy);
-        FwkInfo("DoValidateDeltaTest() -- expectedAfterCreateEvent {0} ,expectedAfterUpdateEvent {1}, expectedAfterDestroyEvent {2} ", expectedAfterCreateEvent, expectedAfterUpdateEvent, expectedAfterDestroyEvent);
-        if (expectedAfterCreateEvent == eventAfterCreate && expectedAfterUpdateEvent == eventAfterUpdate && expectedAfterDestroyEvent == eventAfterDestroy)
-        {
-          DeltaClientValidationListener<TKey, TVal> cs = (region.Attributes.CacheListener) as DeltaClientValidationListener<TKey, TVal>;
-          IDictionary<TKey, Int64> map = cs.getMap();
-          Int32 mapCount = map.Count;
-          Int32 toDeltaMapCount = (Int32)Util.BBGet("MapCount", "size");
-          if (mapCount == toDeltaMapCount)
-          {
-            foreach (KeyValuePair<TKey, Int64> item in map)
-            {
-              key = (TKey)(object)item.Key;
-              Int64 value = item.Value;
-              long fromDeltaCount = (long)value;
-              long toDeltaCount = (long)Util.BBGet("ToDeltaBB", key.ToString());
-              if (toDeltaCount == fromDeltaCount)
-              {
-                FwkInfo("DoValidateDeltaTest() Delta Count Validation success with fromDeltaCount: {0} = toDeltaCount: {1}", fromDeltaCount, toDeltaCount);
-              }
-            }
-            FwkInfo("DoValidateDeltaTest() Validation success.");
-          }
-          else
-          {
-            FwkException("Validation Failed() as fromDeltaMapCount: {0} is not equal to toDeltaMapCount: {1}",mapCount,toDeltaMapCount);
-          }
-        }
-        else
-        {
-          FwkException("Validation Failed()for Region: {0} Expected were expectedAfterCreateEvent {1} expectedAfterUpdateEvent {2} expectedAfterDestroyEvent {3} eventAfterCreate {4}, eventAfterUpdate {5} ", region.Name, expectedAfterCreateEvent, expectedAfterUpdateEvent,expectedAfterDestroyEvent, eventAfterCreate, eventAfterUpdate ,eventAfterDestroy);
-        }
-
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoValidateDeltaTest() Caught Exception: {0}", ex);
-        FwkInfo("DoValidateDeltaTest() complete.");
-      }
-    }
-  }
-}//DeltaTest end
diff --git a/tests/cli/NewFwkLib/DurableTest/DurableClientTests.cs b/tests/cli/NewFwkLib/DurableTest/DurableClientTests.cs
deleted file mode 100644
index 8551969..0000000
--- a/tests/cli/NewFwkLib/DurableTest/DurableClientTests.cs
+++ /dev/null
@@ -1,389 +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.
- */
-
-using System;
-using System.Text;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-
-  public class DurableClientTests<TKey,TVal> : PerfTests<TKey,TVal>
-  {
-    #region Private constants
-
-    private const string KeepAlive = "keepAlive";
-    private const string IsDurable = "isDurable";
-    private const string RestartTime = "restartTime";
-    private const string UpdateReceiveTime = "updateReceiveTime";
-    private const string SleepTime = "sleepTime";
-    private const string RegisterType = "registerType";
-    private const string MissedEvents = "missedEvents";
-    private const string ValueStart = "valueStart";
-    private const string ValueEnd = "valueEnd";
-
-    private static ICacheListener<TKey,TVal> g_listener = null;
-    private static ICacheListener<TKey,TVal> g_perflistener = null;
-    //private static bool isReady = false;
-
-    #endregion
-
-    #region Public methods
-
-    //bool isReady = false;
-
-    public static ICacheListener<TKey,TVal> CreateDurableCacheListener()
-    {
-      g_listener = new DurableListener<TKey,TVal>();
-      return g_listener;
-    }
-    public static ICacheListener<TKey, TVal> CreateConflationTestCacheListenerDC()
-    {
-      g_listener = new ConflationTestCacheListenerDC<TKey,TVal>();
-      return g_listener;
-    }
-    public static ICacheListener<TKey, TVal> CreateDurablePerfListener()
-    {
-      g_perflistener = new DurablePerfListener<TKey,TVal>();
-      return g_perflistener;
-    }
-
-    public void DoIncrementalPuts()
-    {
-      FwkInfo("In DoIncrementalPuts()");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-
-        string keyType = GetStringValue(KeyType); // int is only type to use
-        int keySize = GetUIntValue(KeySize);
-        int numKeys = GetUIntValue(DistinctKeys);
-        Int32 valStart = GetUIntValue(ValueStart);
-        int valEnd = GetUIntValue(ValueEnd);
-
-        // validate the above tags
-
-        char typ = keyType[0] == 'i' ? 'i' : 's';
-
-        Int32 currVal = valStart > 1 ? valStart : 1;
-
-        if (numKeys <= 0)
-        {
-          FwkSevere("Error reading distinctKeys");
-        }
-
-        if (valEnd <= 0)
-        {
-          FwkSevere("Error reading valueEnd");
-        }
-
-        int keyIndex = 0;
-     
-
-        while (true)
-        {
-          if (keyIndex == numKeys)
-          {
-            keyIndex = 1; // start over
-          }
-          else
-          {
-            keyIndex++; // next key
-          }
-
-          if (typ == 'i')
-          {
-            TKey key = (TKey)(object)keyIndex;
-            TVal value =(TVal)(object)currVal;
-            region[key] = value;
-          }
-          else
-          {
-            keySize = keySize > 0 ? keySize : 10;
-            string keyBase = new string('A', keySize);
-            string keyFull = String.Format("{0}{1}", keyBase, keyIndex.ToString("D10"));
-            TKey key = (TKey)(object)(keyFull.ToString());
-            TVal value = (TVal)(object)currVal;
-            region[key] = value;
-          }
-
-          if (++currVal > valEnd)
-          {
-            break;
-          }
-
-          if (currVal % 1000 == 1)
-          {
-            FwkInfo("DurableClientTest: Putting {0}st...", currVal);
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkSevere("DoIncrementalPuts() Caught Exception: {0}", ex);
-        throw;
-      }
-      FwkInfo("DoIncrementalPuts() complete.");
-    }
-
-    public void DoLogDurablePerformance()
-    {
-      DurablePerfListener<TKey, TVal> perflistener = g_perflistener as DurablePerfListener<TKey, TVal>;
-      if (perflistener != null)
-      {
-        FwkInfo("Logging durable performance.");
-        perflistener.logPerformance();
-      }
-    }
-
-    public void DoDurableCloseCache()
-    {
-      FwkInfo("In DoDurableCloseCache()");
-      try
-      {
-        bool keepalive = GetBoolValue(KeepAlive);
-        bool isDurable = GetBoolValue(IsDurable);
-        FwkInfo("KeepAlive is {0}, isDurable is {1}", keepalive, isDurable);
-        if (isDurable && keepalive)
-        {
-          CacheHelper<TKey, TVal>.CloseKeepAlive();
-        }
-        else
-        {
-          CacheHelper<TKey, TVal>.Close();
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkSevere("DoDurableCloseCache() Caught Exception: {0}", ex);
-        throw;
-      }
-      FwkInfo("DoDurableCloseCache() complete.");
-    }
-
-    public override void DoCreateRegion()
-    {
-      FwkInfo("In DoCreateRegion() Durable");
-
-      ClearCachedKeys();
-
-      string rootRegionData = GetStringValue("regionSpec");
-      string tagName = GetStringValue("TAG");
-      string endpoints = Util.BBGet(JavaServerBB, EndPointTag + tagName)
-        as string;
-      if (rootRegionData != null && rootRegionData.Length > 0)
-      {
-        string rootRegionName;
-        rootRegionName = GetRegionName(rootRegionData);
-        if (rootRegionName != null && rootRegionName.Length > 0)
-        {
-          IRegion<TKey, TVal> region;
-          if ((region = CacheHelper<TKey, TVal>.GetRegion(rootRegionName)) == null)
-          {
-            bool isDC = GetBoolValue("isDurable");
-            string m_isPool = null;
-            try
-             {
-              // Check if this is a thin-client region; if so set the endpoints
-              int redundancyLevel = 0;
-              if (endpoints != null && endpoints.Length > 0)
-              {
-                redundancyLevel = GetUIntValue(RedundancyLevelKey);
-                if (redundancyLevel < 0)
-                  redundancyLevel = 0;
-                if (redundancyLevel < 0)
-                  redundancyLevel = 0;
-                string conflateEvents = GetStringValue(ConflateEventsKey);
-                string durableClientId = "";
-                int durableTimeout = 300;
-                if (isDC)
-                {
-                  durableTimeout = GetUIntValue("durableTimeout");
-                  bool isFeeder = GetBoolValue("isFeeder");
-                  if (isFeeder)
-                  {
-                    durableClientId = "Feeder";
-                    // VJR: Setting FeederKey because listener cannot read boolean isFeeder
-                    // FeederKey is used later on by Verify task to identify feeder's key in BB
-                    Util.BBSet("DURABLEBB", "FeederKey", "ClientName_" + Util.ClientNum + "_Count");
-                  }
-                  else
-                  {
-                    durableClientId = String.Format("ClientName_{0}", Util.ClientNum);
-                  }
-                }
-                FwkInfo("DurableClientID is {0} and DurableTimeout is {1}", durableClientId, durableTimeout);
-                ResetKey("sslEnable");
-                bool isSslEnable = GetBoolValue("sslEnable");
-                CacheHelper<TKey, TVal>.InitConfigForPoolDurable(durableClientId, durableTimeout, conflateEvents, isSslEnable);
-               }
-              RegionFactory rootAttrs = CacheHelper<TKey, TVal>.DCache.CreateRegionFactory(RegionShortcut.PROXY);
-              SetRegionAttributes(rootAttrs, rootRegionData, ref m_isPool);
-              rootAttrs = CreatePool(rootAttrs, redundancyLevel);
-              region = CacheHelper<TKey, TVal>.CreateRegion(rootRegionName, rootAttrs);
-              Apache.Geode.Client.RegionAttributes<TKey, TVal> regAttr = region.Attributes;
-              FwkInfo("Region attributes for {0}: {1}", rootRegionName,
-                CacheHelper<TKey, TVal>.RegionAttributesToString(regAttr));
-
-            }
-            catch (Exception ex)
-            {
-              FwkSevere("Caught Exception: {0}", ex);
-            }
-          }
-        }
-        else
-        {
-          FwkSevere("DoCreateRegion() failed to create region");
-        }
-
-      }
-      FwkInfo("DoCreateRegion() complete.");
-    }
-
-    public void DoCloseCacheAndReInitialize()
-    {
-      FwkInfo("In DoCloseCacheAndReInitialize()");
-
-      DoDurableCloseCache();
-
-      //isReady = false;
-      DoRestartClientAndRegInt();
-
-      FwkInfo("DoCloseCacheAndReInitialize() complete.");
-    }
-
-    public void DoRestartClientAndRegInt()
-    {
-      FwkInfo("In DoRestartClientAndRegInt()");
-
-      ClearCachedKeys();
-
-      int sleepSec = GetUIntValue(RestartTime);
-      if (sleepSec > 0)
-      {
-        Thread.Sleep(sleepSec * 1000);
-        FwkInfo("Sleeping for {0} seconds before DoCreateRegion()", sleepSec);
-      }      
-
-      DoCreateRegion();
-
-      string regType = GetStringValue(RegisterType);
-
-      if (regType == "All")
-      {
-        DoRegisterAllKeys();
-      }
-      else if (regType == "List")
-      {
-        DoRegisterInterestList();
-      }
-      else
-      {
-        DoRegisterRegexList();
-      }
-      //isReady = true;
-      int waitSec = GetUIntValue(UpdateReceiveTime);
-      if (waitSec > 0)
-      {
-        Thread.Sleep(waitSec * 1000);
-        FwkInfo("Sleeping for {0} seconds after DoCreateRegion()", sleepSec);
-      }
-
-      FwkInfo("DoRestartClientAndRegInt() complete.");
-    }
-
-    public void DoVerifyEventCount()
-    {
-      FwkInfo("In DoVerifyEventCount()");
-
-      try
-      {
-        bool failed = false;
-
-        string name = String.Format("ClientName_{0}", Util.ClientNum);
-        string operkey = name + "_Count";
-        //string feedkey = "Feeder_Count";
-        string feedkey = (string) Util.BBGet("DURABLEBB", "FeederKey");
-        Int32 currcnt = 0;
-        Int32 feedcnt = 0;
-
-        try
-        {
-          currcnt = (Int32)Util.BBGet("DURABLEBB", operkey);
-        }
-        catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-        {
-          FwkInfo("Key not found for DURABLEBB {0}", operkey);
-        }
-
-        try
-        {
-          feedcnt = (Int32)Util.BBGet("DURABLEBB", feedkey);
-        }
-        catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-        {
-          FwkInfo("Key not found for DURABLEBB {0}", feedkey);
-        }
-
-        FwkInfo("DoVerifyEventCount: Feeder is " + feedcnt + ", Actual is " + currcnt);
-
-        bool missedEvents = GetBoolValue(MissedEvents);
-
-        if (!missedEvents && currcnt != feedcnt)
-        {
-          string clientErrorKey = name + "_ErrMsg";
-          string errorMsg = null;
-          try
-          {
-            errorMsg = (string)Util.BBGet("DURABLEBB", clientErrorKey);
-          }
-          catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-          {
-            errorMsg = "unknown";
-            FwkInfo("Key not found for DURABLEBB {0}", clientErrorKey);
-          }
-          FwkSevere("DoVerifyEventCount: Failed. # Missed = {0}, Err: {1}", feedcnt-currcnt, errorMsg);
-          failed = true;
-        }
-        else if (missedEvents && currcnt > feedcnt)
-        {
-          FwkSevere("DoVerifyEventCount: Failed: Few events should have been missed.");
-          failed = true;
-        }
-
-        FwkAssert(!failed, "DoVerifyEventCount() verification failed");
-      }
-      catch (Exception ex)
-      {
-        FwkSevere("DoVerifyEventCount() Caught Exception: {0}", ex);
-        throw;
-      }
-
-      FwkInfo("DoVerifyEventCount() complete.");
-    }
-
-    public void DoDummyTask()
-    {
-      FwkInfo("DoDummyTask() called.");
-    }
-
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/DurableTest/DurableListener.cs b/tests/cli/NewFwkLib/DurableTest/DurableListener.cs
deleted file mode 100644
index aa7cb90..0000000
--- a/tests/cli/NewFwkLib/DurableTest/DurableListener.cs
+++ /dev/null
@@ -1,256 +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.
- */
-
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-
-  public class DurableListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>, IDisposable
-  {
-    #region Private members
-
-    int m_ops = 0;
-    string m_clientName = null;
-    Int32 m_prevValue = 0;
-    bool m_result = true;
-    string m_err;
-
-    #endregion
-
-    #region Private methods
-
-    private void check(EntryEvent<TKey, TVal> ev)
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-
-     // CacheableInt32 value = ev.NewValue as CacheableInt32;
-      Int32 value = (Int32)(object)ev.NewValue;
-
-      if (value <= m_prevValue) // duplicate
-      {
-        //currTest.FwkInfo("DurableListener : duplicate value: " + value.Value);
-      }
-      else if (value == m_prevValue + 1) // desired
-      {
-        m_ops++;
-        m_prevValue++;
-      }
-      else // event missed
-      {
-        currTest.FwkInfo("Missed event, expected {0}, actual {1}", m_prevValue + 1, value);
-        m_prevValue = value;
-        m_ops++;
-        if (m_result)
-        {
-          m_result = false;
-          m_err = String.Format("Missed event with value {0}", value);
-          currTest.FwkInfo("Missed event, expected {0}, actual {1}", m_prevValue + 1, value);
-        }
-      }
-    }
-    
-    private void dumpToBB()
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      currTest.FwkInfo("DurableListener: updating blackboard, ops = {0}, prev = {1}", m_ops, m_prevValue);
-
-      // increment count
-      string bbkey = m_clientName + "_Count";
-      Int32 current = 0;
-      try
-      {
-        current = (Int32)Util.BBGet("DURABLEBB", bbkey);
-      }
-      catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-      {
-        currTest.FwkInfo("Key not found for DURABLEBB {0}", bbkey);
-      }
-      current += m_ops;
-      Util.BBSet("DURABLEBB", bbkey, current);
-      currTest.FwkInfo("Current count for " + bbkey + " is " + current);
-
-      // set current index
-      string clientIndexKey = m_clientName + "_IDX";
-      Util.BBSet("DURABLEBB", clientIndexKey, m_prevValue);
-
-      // store error message
-      if (!m_result && m_err != null && m_err.Length > 0)
-      {
-        string clientErrorKey = m_clientName + "_ErrMsg";
-        string clientErrorVal = null;
-        try
-        {
-          clientErrorVal = (string)Util.BBGet("DURABLEBB", clientErrorKey);
-        }
-        catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-        {
-          currTest.FwkInfo("Key not found for DURABLEBB {0}", clientErrorKey);
-        }
-        if (clientErrorVal == null || clientErrorVal.Length <= 0)
-        {
-          Util.BBSet("DURABLEBB", clientErrorKey, m_err);
-        }
-      }
-    }
-
-    #endregion
-
-    #region ICacheListener Members
-
-    public override void AfterCreate(EntryEvent<TKey,TVal> ev)
-    {
-      check(ev);
-    }
-
-    public override void AfterRegionLive(RegionEvent<TKey, TVal> ev)
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      currTest.FwkInfo("DurableListener: AfterRegionLive invoked");
-    }
-
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      check(ev);
-    }
-
-    public override void Close(IRegion<TKey, TVal> region)
-    {
-      dumpToBB();
-    }
-    public override void AfterRegionDisconnected(IRegion<TKey, TVal> region)
-    {
-    }
-    #endregion
-
-    protected virtual void Dispose(bool disposing)
-    {
-    }
-
-    #region IDisposable Members
-
-    public void Dispose()
-    {
-      Dispose(true);
-      GC.SuppressFinalize(this);
-    }
-
-    #endregion
-
-    public DurableListener()
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest; 
-      m_clientName = String.Format("ClientName_{0}", Util.ClientNum);
-      string clientIndexKey = m_clientName + "_IDX";
-      try
-      {
-        m_prevValue = (Int32)Util.BBGet("DURABLEBB", clientIndexKey);
-      }
-      catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-      {
-        m_prevValue = 0;
-        currTest.FwkInfo("Key not found for DURABLEBB {0}", clientIndexKey);
-      }
-      currTest.FwkInfo("DurableListener created for client {0} with prev val {1}", m_clientName, m_prevValue);
-    }
-
-    ~DurableListener()
-    {
-      Dispose(false);
-    }
-  }
-
-  public class ConflationTestCacheListenerDC<TKey, TVal> : ICacheListener<TKey, TVal>
-  {
-    int m_numAfterCreate;
-    int m_numAfterUpdate;
-    int m_numAfterInvalidate;
-    int m_numAfterDestroy;
-
-    public ConflationTestCacheListenerDC()
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Calling durable client ConflationTestCacheListener");
-      m_numAfterCreate = 0;
-      m_numAfterUpdate = 0;
-      m_numAfterInvalidate = 0;
-      m_numAfterDestroy = 0;
-    }
-
-    public static ICacheListener<TKey, TVal> Create()
-    {
-      return new ConflationTestCacheListenerDC<TKey, TVal>();
-    }
-    ~ConflationTestCacheListenerDC() { }
-    
-    #region ICacheListener Members
-
-    public void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterCreate;
-    }
-
-    public void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterUpdate;
-    }
-    public void AfterRegionLive(RegionEvent<TKey, TVal> ev)
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("ConflationTestCacheListener: AfterRegionLive invoked");
-    }
-    public void AfterDestroy(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterDestroy;
-    }
-
-    public void AfterInvalidate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterInvalidate;
-    }
-
-    public void AfterRegionDestroy(RegionEvent<TKey, TVal> ev)
-    {
-      dumpToBB(ev.Region);
-    }
-
-    public void AfterRegionClear(RegionEvent<TKey, TVal> ev)
-    {
-    }
-
-    public void AfterRegionInvalidate(RegionEvent<TKey, TVal> ev)
-    {
-    }
-
-    public void Close(IRegion<TKey, TVal> region)
-    {
-    }
-    public void AfterRegionDisconnected(IRegion<TKey, TVal> region)
-    {
-    }
-    private void dumpToBB(IRegion<TKey, TVal> region)
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("dumping durable client data on BB for ConflationTestCacheListener");
-      Util.BBSet("ConflationCacheListener", "AFTER_CREATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterCreate);
-      Util.BBSet("ConflationCacheListener", "AFTER_UPDATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterUpdate);
-      Util.BBSet("ConflationCacheListener", "AFTER_DESTROY_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterDestroy);
-      Util.BBSet("ConflationCacheListener", "AFTER_INVALIDATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterInvalidate);
-    }
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/DurableTest/DurablePerfListener.cs b/tests/cli/NewFwkLib/DurableTest/DurablePerfListener.cs
deleted file mode 100644
index 5d7f105..0000000
--- a/tests/cli/NewFwkLib/DurableTest/DurablePerfListener.cs
+++ /dev/null
@@ -1,135 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-
-
-  public class DurablePerfListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>, IDisposable
-  {
-    #region Private members
-
-    long m_ops = 0;
-    long m_minTime;
-    DateTime m_prevTime;
-    DateTime m_startTime;
-    
-    #endregion
-
-    #region Private methods
-
-    private void recalculate(EntryEvent<TKey, TVal> ev)
-    {
-      if (m_ops == 0)
-      {
-        m_startTime = DateTime.Now;
-      }
-
-      m_ops++;
-
-      if (m_ops % 1000 == 0)
-      {
-        FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-        currTest.FwkInfo("DurablePerfListener : m_ops = " + m_ops);
-      }
-
-      DateTime currTime = DateTime.Now;
-      TimeSpan elapsedTime = currTime - m_prevTime;
-
-      long diffTime = elapsedTime.Milliseconds;
-
-      if (diffTime < m_minTime)
-      {
-        m_minTime = diffTime;
-      }
-
-      m_prevTime = currTime;
-    }
-    
-    #endregion
-
-    #region ICacheListener Members
-
-    public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-      recalculate(ev);
-    }
-
-
-    public override void AfterRegionLive(RegionEvent<TKey, TVal> ev)
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      currTest.FwkInfo("DurablePerfListener: AfterRegionLive invoked.");
-    }
-
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      recalculate(ev);
-    }
-
-    public override void Close(IRegion<TKey, TVal> region)
-    {
-    }
-    public override void AfterRegionDisconnected(IRegion<TKey, TVal> region)
-    {
-    }
-    #endregion
-
-    protected virtual void Dispose(bool disposing)
-    {
-    }
-
-    #region IDisposable Members
-
-    public void Dispose()
-    {
-      Dispose(true);
-      GC.SuppressFinalize(this);
-    }
-
-    #endregion
-
-    public void logPerformance()
-    {
-      TimeSpan totalTime = m_prevTime - m_startTime;
-      double averageRate = m_ops / totalTime.TotalSeconds;
-      double maxRate = 1000.0 / m_minTime;
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      currTest.FwkInfo("DurablePerfListener: # events = {0}, max rate = {1} events per second.", m_ops, maxRate);
-      currTest.FwkInfo("DurablePerfListener: average rate = {0} events per second, total time {1} seconds", averageRate, totalTime.TotalSeconds);
-    }
-
-    public DurablePerfListener()
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      currTest.FwkInfo("DurablePerfListener: created");
-      m_minTime = 99999999;
-      m_prevTime = DateTime.Now;
-    }
-
-    ~DurablePerfListener()
-    {
-      Dispose(false);
-    }
-  }
-}
diff --git a/tests/cli/NewFwkLib/EventTest/ETCacheListener.cs b/tests/cli/NewFwkLib/EventTest/ETCacheListener.cs
deleted file mode 100644
index 94644a8..0000000
--- a/tests/cli/NewFwkLib/EventTest/ETCacheListener.cs
+++ /dev/null
@@ -1,83 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.FwkLib
-{
-
-  using Apache.Geode.DUnitFramework;
-
-  public class ETCacheListener : ICacheListener
-  {
-    public static ICacheListener Create()
-    {
-      return new ETCacheListener();
-    }
-
-    #region ICacheListener Members
-
-    public void AfterCreate(EntryEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "AFTER_CREATE_COUNT");
-    }
-
-    public void AfterDestroy(EntryEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "AFTER_DESTROY_COUNT");
-    }
-
-    public void AfterInvalidate(EntryEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "AFTER_INVALIDATE_COUNT");
-    }
-
-    public void AfterRegionDestroy(RegionEvent ev)
-    {
-      //Util.BBIncrement("AFTER_REGION_DESTROY_COUNT");
-    }
-
-    public void AfterRegionInvalidate(RegionEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "AFTER_REGION_INVALIDATE_COUNT");
-    }
-    public void AfterRegionClear(RegionEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "AFTER_REGION_CLEAR_COUNT");
-    }
-
-
-    public void AfterUpdate(EntryEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "AFTER_UPDATE_COUNT");
-    }
-
-    public virtual void AfterRegionLive(RegionEvent ev)
-    {
-      //Util.BBIncrement("AFTER_REGION_LIVE_COUNT");
-    }
-
-    public void Close(Region region)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "CLOSE_COUNT");
-    }
-    public void AfterRegionDisconnected(Region region)
-    {
-    }
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/EventTest/ETCacheLoader.cs b/tests/cli/NewFwkLib/EventTest/ETCacheLoader.cs
deleted file mode 100644
index 3b63629..0000000
--- a/tests/cli/NewFwkLib/EventTest/ETCacheLoader.cs
+++ /dev/null
@@ -1,49 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-
-  public class ETCacheLoader : ICacheLoader
-  {
-    public static ICacheLoader Create()
-    {
-      return new ETCacheLoader();
-    }
-
-    #region ICacheLoader Members
-
-    public ISerializable Load(Region rp, ICacheableKey key, ISerializable helper)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "LOAD_CACHEABLE_STRING_COUNT");
-      byte[] buffer = new byte[2000];
-      Util.RandBytes(buffer);
-      CacheableBytes value = CacheableBytes.Create(buffer);
-      return value;
-    }
-
-    public void Close(Region rp)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "CLOSE_COUNT");
-    }
-
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/EventTest/ETCacheWriter.cs b/tests/cli/NewFwkLib/EventTest/ETCacheWriter.cs
deleted file mode 100644
index 090185c..0000000
--- a/tests/cli/NewFwkLib/EventTest/ETCacheWriter.cs
+++ /dev/null
@@ -1,69 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-
-  public class ETCacheWriter : ICacheWriter
-  {
-    public static ICacheWriter Create()
-    {
-      return new ETCacheWriter();
-    }
-
-    #region ICacheWriter Members
-
-    public bool BeforeUpdate(EntryEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "BEFORE_UPDATE_COUNT");
-      return true;
-    }
-
-    public bool BeforeCreate(EntryEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "BEFORE_CREATE_COUNT");
-      return true;
-    }
-
-    public bool BeforeDestroy(EntryEvent ev)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "BEFORE_DESTROY_COUNT");
-      return true;
-    }
-    public bool BeforeRegionClear(RegionEvent rv)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "BEFORE_REGION_CLEAR_COUNT");
-      return true;
-    }
-
-    public bool BeforeRegionDestroy(RegionEvent rv)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "BEFORE_REGION_DESTROY_COUNT");
-      return true;
-    }
-
-    public void Close(Region rv)
-    {
-      Util.BBIncrement(EventTest.EventCountersBB, "CLOSE_COUNT");
-    }
-
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/EventTest/EventTests.cs b/tests/cli/NewFwkLib/EventTest/EventTests.cs
deleted file mode 100644
index cf04918..0000000
--- a/tests/cli/NewFwkLib/EventTest/EventTests.cs
+++ /dev/null
@@ -1,1774 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using System.Threading;
-  using System.Xml.Serialization;
-  using System.IO;
-  using System.Reflection;
-
-  public class EventTest : FwkTest
-  {
-    public const string EventCountersBB = "EventCountersBB";
-
-    #region Private members
-
-    private List<CacheableKey> m_keysVec = new List<CacheableKey>();
-
-    #endregion
-
-    #region Private utility methods
-
-    private int percentDifferent()
-    {
-      string testRegionName = GetStringValue("regionName");
-      if (testRegionName.Length == 0)
-      {
-        throw new FwkException("Data not provided for regionname failing");
-      }
-      int bbExpected = 0;
-      int expected = GetUIntValue("expectedKeyCount");
-      if (expected < 0)
-      {
-        bbExpected = (int)Util.BBGet(EventCountersBB, "CREATE_COUNT");
-        if (bbExpected <= 0)
-        {
-          throw new FwkException("Data not provided for expectedKeyCount failing");
-        }
-        expected = bbExpected;
-      }
-      Region testReg = CacheHelper.GetRegion(testRegionName);
-      ISerializable[] keys = testReg.GetKeys();
-      int keyCount = keys.Length;
-      double diff = 0;
-      if (keyCount > expected)
-      {
-        diff = keyCount - expected;
-      }
-      else
-      {
-        diff = expected - keyCount;
-      }
-      int retval = (int)((diff / ((double)expected + 1.0)) * 100.0);
-      FwkInfo("Expected to have " + expected + " keys, found " + keyCount + " keys, percent Difference: " + retval);
-      return retval;
-    }
-
-    private void doEntryTest(string opcode)
-    {
-      FwkInfo("Calling doEntryTest inside getRandomregion");
-      Region reg = GetRandomRegion(true);
-      FwkInfo("After getrandomregion inside doentrytest");
-      if (reg == null)
-      {
-        FwkInfo("Check in side doEntryTest ... No region to operate on");
-        throw new FwkException("No reion to operate on");
-      }
-
-      lock (this)
-      {
-        FwkInfo("After getrandomregion inside doentrytest Check 1");
-        if (reg.Attributes.CachingEnabled == false)
-        {
-          return;
-        }
-        ISerializable[] keys = reg.GetKeys();
-        int maxkeys = GetUIntValue("distinctKeys");
-        int balanceEntries = GetUIntValue("balanceEntries");
-        FwkInfo("After getrandomregion inside doentrytest Check 2 balance entries = {0}", balanceEntries);
-        if (balanceEntries > 0)
-        {
-          if (keys.Length >= maxkeys)
-          {
-            FwkInfo("Balancing cache content by destroying excess entries.");
-            int dcnt = 0;
-            for (uint i = 100; i > 0; i--)
-            {
-              try
-              {
-                destroyObject(reg, true);
-              }
-              catch (Exception e)
-              {
-                // ignore the exception ... TODO print the message
-                FwkSevere(e.Message);
-              }
-            }
-            FwkInfo("Cache balancing complete, did " + dcnt + " destroys.");
-          }
-          else if (keys.Length == 0)
-          {
-            FwkInfo("Balancing cache content by creating entries.");
-            int ccnt = 0;
-            for (int i = 100; i > 0; i--)
-            {
-              try
-              {
-                addObject(reg, true, null, null);
-                ccnt++;
-              }
-              catch (TimeoutException e)
-              {
-                FwkSevere("Caught unexpected timeout exception during entry " + opcode
-                  + " operation: " + e.Message + " continuing with test.");
-              }
-              catch (Exception e)
-              {
-                // Ignore other exception ... @TODO
-                FwkInfo("Ignoring exception " + e.Message);
-              }
-            }
-            FwkInfo("Cache balancing complete, did " + ccnt + " creates.");
-          }
-        }
-        else
-        {
-          FwkInfo("Balance entries less than zero");
-        }
-      }
-      FwkInfo("After getrandomregion inside doentrytest Check 4 before switch opcode = {0}", opcode);
-      //opcode = "read";
-      FwkInfo("opcode = " + opcode.ToString() + " " + opcode);
-
-
-      switch (opcode)
-      {
-        case "add":
-          addObject(reg, true, null, null);
-          break;
-
-        case "update":
-          updateObject(reg);
-          break;
-
-        case "invalidate":
-          invalidateObject(reg, false);
-          break;
-
-        case "destroy":
-          destroyObject(reg, false);
-          break;
-
-        case "read":
-          readObject(reg);
-          break;
-
-        case "localInvalidate":
-          invalidateObject(reg, true);
-          break;
-
-        case "localDestroy":
-          destroyObject(reg, true);
-          break;
-
-        default:
-          FwkSevere("Invalid operation specified: " + opcode);
-          break;
-
-      }
-    }
-
-    private void doRegionTest(string opcode, int iMaxRegions)
-    {
-      Region randomRegion;
-      lock (this)
-      {
-        int iRegionCount = getAllRegionCount();
-        if (iRegionCount >= iMaxRegions)
-        {
-          while (iRegionCount > iMaxRegions / 2)
-          {
-            try
-            {
-              randomRegion = GetRandomRegion(true);
-              if (randomRegion == null)
-              {
-                FwkException("expected to get a valid random region, get a null region instead");
-              }
-              else
-              {
-                destroyRegion(randomRegion, false);
-              }
-              iRegionCount = getAllRegionCount();
-              FwkInfo("Inside doregiontest ... iregioncount = {0}", iRegionCount);
-            }
-            catch (Exception ignore)
-            {
-              FwkInfo(ignore.Message);
-            }
-          }
-        }
-        else if (iRegionCount <= 0)
-        {
-          for (Int32 i = iMaxRegions / 2; i > 0; i--)
-          {
-            try
-            {
-              addRegion();
-            }
-            catch (Exception ignore)
-            {
-              FwkInfo(ignore.Message);
-            }
-          }
-        }
-        FwkInfo("Inside doregiontest after else");
-      }
-
-      FwkInfo("Again GetRandomRegion");
-      randomRegion = GetRandomRegion(true);
-      if (randomRegion == null)
-      {
-        //need to create a region
-        opcode = "addRegion";
-      }
-      FwkInfo("Do region test: " + opcode);
-      switch (opcode)
-      {
-        case "addRegion":
-          addRegion();
-          break;
-        case "clearRegion":
-          clearRegion(randomRegion, false);
-          break;
-
-        case "invalidateRegion":
-          invalidateRegion(randomRegion, false);
-          break;
-
-        case "destroyRegion":
-          destroyRegion(randomRegion, false);
-          break;
-
-        case "localClearRegion":
-          clearRegion(randomRegion, true);
-          break;
-
-        case "localInvalidateRegion":
-          invalidateRegion(randomRegion, true);
-          break;
-
-        case "localDestroyRegion":
-          destroyRegion(randomRegion, true);
-          break;
-
-        default:
-          FwkSevere("Invalid operation specified: " + opcode);
-          break;
-      }
-    }
-
-    private string getNextRegionName(Region region)
-    {
-      string regionName = null;
-      int count = 0;
-      string path;
-      do
-      {
-        path = GetStringValue("regionPaths");
-        if (path.Length == 0)
-        {
-          FwkException("No regionPaths defined in the xml file. Needed for region event test");
-        }
-        do
-        {
-          int length = path.Length;
-          try
-          {
-            region = CacheHelper.GetRegion(path);
-          }
-          catch (Exception e)
-          {
-            FwkSevere(e.Message);
-          }
-          if (region == null)
-          {
-            int pos = path.LastIndexOf('/');
-            regionName = path.Substring(pos + 1, path.Length - pos);
-            path = path.Substring(0, pos);
-          }
-        } while ((region == null) && path.Length == 0);
-      } while ((++count < 5) && regionName.Length != 0);
-      return regionName;
-    }
-
-    public void measureMemory(string s, double vs, double rs)
-    {
-    }
-
-    public CacheableKey findKeyNotInCache(Region region)
-    {
-      CacheableKey key;
-      if (m_keysVec.Count == 0)
-      {
-        lock (this)
-        {
-          int numKeys = GetUIntValue("distinctKeys");
-          for (int i = 0; i < numKeys; i++)
-          {
-            string skey = i.ToString();
-            key = new CacheableString(skey);
-            //int pos = m_keysVec.Length;
-            m_keysVec.Add(key);
-          }
-        }
-      }
-      key = null;
-
-      int start = Util.Rand(m_keysVec.Count);
-      bool wrapped = false;
-      int cur = start;
-      while ((cur != start) || !wrapped)
-      {
-        if (cur >= m_keysVec.Count)
-        {
-          cur = 0;
-          wrapped = true;
-        }
-        else
-        {
-          if (!region.ContainsKey(m_keysVec[cur]))
-          {
-            key = m_keysVec[cur];
-            cur = start;
-            wrapped = true;
-          }
-          else
-          {
-            cur++;
-          }
-        }
-      }
-      return key;
-    }
-
-    #endregion
-
-    #region Public methods
-
-    public void DoEntryOperations()
-    {
-      Util.Log("Calling doeventoperations");
-      doEventOperations();
-    }
-
-
-    public void doEventOperations()
-    {
-      UInt32 counter = 0;
-      string taskID = "begin";
-      // Clear up everything from previous test.
-      // Make sure we have one root region.
-      {
-        // TODO: Lock and task id business
-        // ACE_Guard<ACE_Thread_Mutex> guard( *testLock);
-        //if ((taskID != null) && (this.getn != taskID))
-        {
-          // TODO
-          CacheHelper.DestroyAllRegions(true);
-          //destroyAllRegions();
-
-          CreateRootRegion();
-          if (taskID != null)
-          {
-            //(taskID);
-          }
-          //  FWKINFO( "DBG doEventOperations set id" );
-          //taskID = strdup(getTaskId().c_str());
-        }
-        //  FWKINFO( "DBG doEventOperations release lock" );
-      }
-      int workTime = GetUIntValue("workTime");
-      FwkInfo("doEventOperations will work for " + workTime + " seconds. ");
-
-      int skipCounter = GetUIntValue("skipCount");
-      skipCounter = (skipCounter > 0) ? skipCounter : 100;
-
-      int iMaxRegions = GetUIntValue("maxRegions");
-      // TODO: DEFAULT_MAX_REGION
-      int DEFAULT_MAX_REGION = 10;
-      iMaxRegions = (iMaxRegions > 0) ? iMaxRegions : DEFAULT_MAX_REGION;
-
-      // TODO: check the correctness.
-      DateTime endTime = DateTime.Now + TimeSpan.FromMilliseconds((double)workTime);
-
-      int opsSecond = GetUIntValue("opsSecond");
-      opsSecond = (opsSecond > 0) ? opsSecond : 0;
-      PaceMeter pm = new PaceMeter(opsSecond);
-
-      int logSize = GetUIntValue("logSize");
-
-      int opCount = 0;
-
-      DateTime now = new DateTime();
-      string opcode = string.Empty;
-      bool isDone = false;
-      FwkInfo("Entering event loop.");
-      do
-      {
-        FwkInfo("Before getRegionCount");
-        if (logSize == 1)
-        {
-          int cnt = getRegionCount();
-          FwkInfo(cnt + ((cnt == 1) ? " region " : " regions ") + opCount);
-        }
-        FwkInfo("After getRegionCount");
-        int randomOP = GetUIntValue("randomOP");
-        if (randomOP == 5)
-        {
-          opcode = GetStringValue("regionOps");
-        }
-        else
-        {
-          opcode = GetStringValue("entryOps");
-        }
-        FwkInfo("Check 1");
-        if (opcode.Length != 0)
-        {
-          bool skipTest = false;
-          if (opcode == "abort")
-          {
-            skipTest = true;
-            if (--skipCounter == 0)
-            {
-              // TODO: definitely wrong. what is intended is unclear.
-              //char * segv = NULL;
-              //strcpy( segv, "Forcing segv" );
-            }
-          }
-          else if (opcode == "exit")
-          {
-            skipTest = true;
-            if (--skipCounter == 0)
-            {
-              Environment.Exit(0);
-            }
-          }
-          else if (opcode == "done")
-          {
-            skipTest = true;
-            if (--skipCounter == 0)
-            {
-              isDone = true;
-            }
-          }
-
-          if (!skipTest)
-          {
-            FwkInfo("Check 2 doRegionTest");
-            if (randomOP == 5)
-            {
-              doRegionTest(opcode, iMaxRegions);
-            }
-            else
-            {
-              FwkInfo("Check 3 doEntryTest");
-              doEntryTest(opcode);
-              FwkInfo("Check 4 doentrytest over");
-            }
-            opCount++;
-            pm.CheckPace();
-          }
-          counter++;
-          if ((counter % 1000) == 0)
-          {
-            FwkInfo("Performed " + counter + " operations.");
-          }
-          Util.BBIncrement(EventCountersBB, "CURRENT_OPS_COUNT");
-        }
-        else
-        {
-          FwkSevere("NULL operation specified." + "randomOP: " + randomOP);
-        }
-        now = DateTime.Now;
-        FwkInfo("do while end in doeventoperations");
-      } while ((now < endTime) && !isDone);
-
-      FwkInfo("Event loop complete.");
-      FwkInfo("doEventOperations() performed " + counter + " operations.");
-    }
-
-    public void doIterate()
-    {
-      FwkInfo("doIterate()");
-      uint ulKeysInRegion = 0;
-      uint ulNoneNullValuesInRegion = 0;
-      string sError = null;
-
-      Region[] rootRegionArray;
-      Region rootRegion;
-      RegionAttributes attr;
-
-      rootRegionArray = CacheHelper<TKey, TVal>.DCache.RootRegions();
-
-      int ulRegionCount = rootRegionArray.Length;
-
-      for (int ulIndex = 0; ulIndex < ulRegionCount; ulIndex++)
-      {
-        rootRegion = rootRegionArray[ulIndex];
-        attr = rootRegion.Attributes;
-
-        bool bHasInvalidateAction = attr.EntryIdleTimeoutAction == ExpirationAction.Invalidate ||
-          (attr.EntryTimeToLiveAction == ExpirationAction.Invalidate);
-
-        iterateRegion(rootRegion, true, bHasInvalidateAction, ulKeysInRegion, ulNoneNullValuesInRegion, sError);
-
-        if (sError.Length > 0)
-        {
-          FwkException(sError);
-        }
-      }
-    }
-
-    public void doMemoryMeasurement()
-    {
-      // TODO Later
-
-    }
-
-    public void verifyKeyCount()
-    {
-      int percentDiff = percentDifferent();
-      if (percentDiff > 10)
-      {
-        FwkSevere("Actual number of keys does not match expected number.");
-      }
-    }
-
-    public void addEntry()
-    {
-      string testRegionName = GetStringValue("regionName");
-      if (testRegionName.Length == 0)
-      {
-        FwkException("Data not provided for 'regionName', failing.");
-      }
-      Region region = CacheHelper<TKey, TVal>.DCache.GetRegion(testRegionName);
-
-      int usePid = GetUIntValue("usePID");
-      int pid = Util.PID;
-
-      int opsSecond = GetUIntValue("opsSecond");
-      if (opsSecond < 0)
-      {
-        opsSecond = 0; // No throttle
-      }
-      PaceMeter pm = new PaceMeter(opsSecond);
-
-      int entryCount = GetUIntValue("EntryCount");
-      if (entryCount <= 0)
-      {
-        entryCount = 100;
-      }
-      FwkInfo("addEntry: Adding " + entryCount + " entries to the cache.");
-
-      for (Int32 count = 0; count < entryCount; count++)
-      {
-        string sKey;
-        Serializable sValue;
-
-        if (usePid == 1)
-        {
-          sKey = pid.ToString();
-        }
-        else
-        {
-          sKey = string.Empty;
-        }
-
-        sKey += count.ToString();
-        // get value size
-        int vsize = GetUIntValue("valueSizes");
-        if (vsize < 0)
-        {
-          vsize = 1000;
-        }
-
-        byte[] buffer = new byte[vsize];
-        Util.RandBytes(buffer);
-        sValue = CacheableBytes.Create(buffer);
-
-        // TODO: check
-        CacheableKey key = new CacheableString(sKey);
-        Serializable value = sValue;
-
-        if (key == null)
-        {
-          FwkSevere("EventTest::addObject null keyPtr generated.");
-        }
-
-        FwkInfo("created entry with key: " + key.ToString());
-        region.Put(key as CacheableKey, value);
-        Util.BBIncrement(EventCountersBB, "CREATE_COUNT");
-        pm.CheckPace();
-      }
-      FwkInfo("addEntry: Complete.");
-    }
-
-    public void addOrDestroyEntry()
-    {
-      string testRegionName = GetStringValue("regionName");
-      if (testRegionName.Length == 0)
-      {
-        FwkException("Data not provided for 'regionName', failing.");
-      }
-      Region region = CacheHelper<TKey, TVal>.DCache.GetRegion(testRegionName);
-
-      int usePid = GetUIntValue("usePID");
-      int pid = Util.PID;
-
-      int entryCount = GetUIntValue("EntryCount");
-      if (entryCount <= 0)
-      {
-        entryCount = 100;
-      }
-      FwkInfo("addOrDestroyEntry: Adding or Destroying ( if present )" + entryCount + " entries to the cache.");
-      for (int count = 0; count < entryCount; count++)
-      {
-        string sKey;
-
-        if (usePid == 1)
-        {
-          sKey = pid.ToString();
-        }
-        else
-        {
-          sKey = string.Empty;
-        }
-
-        sKey += count.ToString();
-        // get value size
-        int vsize = GetUIntValue("valueSizes");
-        if (vsize < 0)
-        {
-          vsize = 1000;
-        }
-        byte[] buffer = new byte[vsize];
-        Util.RandBytes(buffer);
-        CacheableKey key = new CacheableString(sKey);
-        CacheableBytes value = CacheableBytes.Create(buffer);
-
-        if (key == null)
-        {
-          FwkSevere("EventTest::addObject null keyPtr generated.");
-        }
-
-        string op = GetStringValue("popOp");
-        if (op == "put")
-        {
-          region.Put(key as CacheableKey, value);
-        }
-        else
-        {
-          region.Destroy(key as CacheableKey);
-        }
-
-        Util.BBIncrement(EventCountersBB, "CREATE_COUNT");
-      }
-      FwkInfo("addOrDestroyEntry: Complete.");
-    }
-
-    public void validateCacheContent()
-    {
-      FwkInfo("validateCacheContent()");
-      string testRegionName = GetStringValue("testRegion");
-      string validateRegionName = GetStringValue("validateRegion");
-      Region testRegion = CacheHelper<TKey, TVal>.DCache.GetRegion(testRegionName);
-      Region validateRegion = CacheHelper<TKey, TVal>.DCache.GetRegion(validateRegionName);
-      ICacheableKey[] keyVector;
-
-      keyVector = testRegion.GetKeys();
-      int ulKeysInRegion = keyVector.Length;
-      if (ulKeysInRegion == 0)
-      {
-        FwkSevere("zero keys in testRegion " + testRegion.Name);
-      }
-
-      ICacheableKey key;
-      ISerializable value;
-
-      int entryPassCnt = 0;
-      int entryFailCnt = 0;
-
-      for (int ulIndex = 0; ulIndex < ulKeysInRegion; ulIndex++)
-      {
-        key = keyVector[ulIndex];
-        value = testRegion.Get(key);
-
-        if (TestEntryPropagation(validateRegion, key as CacheableString, value as CacheableBytes))
-        {
-          entryFailCnt++;
-        }
-        else
-        {
-          entryPassCnt++;
-        }
-      }
-      FwkInfo("entryFailCnt is " + entryFailCnt + " entryPassCnt is " + entryPassCnt);
-      if (entryFailCnt == 0)
-      {
-        FwkInfo("validateCacheContent() - TEST ENDED, RESULT = SUCCESSFUL ");
-      }
-      else
-      {
-        FwkSevere("validateCacheContent() - TEST ENDED, RESULT = FAILED ");
-      }
-    }
-
-    public void validateRegionContent()
-    {
-      FwkInfo("validateRegionContent()");
-      string testRegionName = GetStringValue("testRegion");
-      string validateRegionName = GetStringValue("validateRegion");
-      string regionName = GetStringValue("regionName");
-      Region testRegion = CacheHelper<TKey, TVal>.DCache.GetRegion(testRegionName);
-      Region validateRegion = CacheHelper<TKey, TVal>.DCache.GetRegion(validateRegionName);
-
-      FwkInfo("localDestroyRegion region name is " + testRegion.Name);
-      // destroy the region
-      int iBeforeCounter = (int)Util.BBGet(EventCountersBB,
-        "numAfterRegionDestroyEvents_isNotExp");
-
-      testRegion.LocalDestroyRegion();
-      CreateRootRegion();
-      Region region = CacheHelper<TKey, TVal>.DCache.GetRegion(regionName);
-
-      FwkInfo(" Recreated Region name is " + region.Name);
-
-      ICacheableKey[] keyVector;
-      ICacheableKey[] keyVectorValidateRegion;
-
-      keyVector = region.GetKeys();
-      keyVectorValidateRegion = validateRegion.GetKeys();
-      int ulKeysInRegion = keyVector.Length;
-      int ulKeysInValidateRegion = keyVectorValidateRegion.Length;
-      if (ulKeysInRegion != ulKeysInValidateRegion)
-      {
-        FwkSevere("Region Key count is not equal, Region " + region.Name + " key count is " + ulKeysInRegion + " and Region " +
-           validateRegion.Name + " key count is " + ulKeysInValidateRegion);
-      }
-
-      ICacheableKey key;
-      ISerializable value;
-
-      int entryPassCnt = 0;
-      int entryFailCnt = 0;
-      for (int ulIndex = 0; ulIndex < ulKeysInRegion; ulIndex++)
-      {
-        key = keyVector[ulIndex];
-        value = region.Get(key);
-
-        if (TestEntryPropagation(validateRegion, key as CacheableString, value as CacheableBytes))
-        {
-          entryFailCnt++;
-        }
-        else
-        {
-          entryPassCnt++;
-        }
-      }
-      FwkInfo("entryFailCnt is " + entryFailCnt + " entryPassCnt is " + entryPassCnt);
-      if (entryFailCnt == 0)
-      {
-        FwkInfo("validateRegionContent() - TEST ENDED, RESULT = SUCCESSFUL ");
-      }
-      else
-      {
-        FwkSevere("validateRegionContent() - TEST ENDED, RESULT = FAILED ");
-      }
-    }
-
-    public void doCreateObject()
-    {
-      // Not implemented.
-    }
-
-    public void doIterateOnEntry()
-    {
-      FwkInfo("doIterateOnEntry()");
-      string testRegionName = GetStringValue("testRegion");
-      string validateRegionName = GetStringValue("validateRegion");
-      Region testRegion = CacheHelper<TKey, TVal>.DCache.GetRegion(testRegionName);
-      Region validateRegion = CacheHelper<TKey, TVal>.DCache.GetRegion(validateRegionName);
-
-      ICacheableKey[] keyVector = null;
-      int keysInRegion = 1;
-      int lastCount = 0;
-      int tryCount = 30;
-      int tries = 0;
-
-      while ((keysInRegion != lastCount) && (tries++ < tryCount))
-      {
-        Thread.Sleep(10000); // sleep for 10 seconds.
-        lastCount = keysInRegion;
-        keyVector = testRegion.GetKeys();
-        keysInRegion = keyVector.Length;
-      }
-
-      if ((keysInRegion == 0) || (tries >= tryCount))
-      {
-        FwkException("After " + tries + " tries, counted " + keysInRegion + " keys in the region.");
-      }
-
-      FwkInfo("After " + tries + " tries, counted " + keysInRegion + " keys in the region.");
-
-      CacheableKey key;
-      Serializable value;
-
-      for (int index = 0; index < keysInRegion; index++)
-      {
-        key = keyVector[index] as CacheableKey;
-        value = testRegion.Get(key) as Serializable;
-        validateRegion.Create(key, value);
-      }
-    }
-
-    public void feedEntries()
-    {
-      string testRegionName = GetStringValue("regionName");
-      if (testRegionName.Length == 0)
-      {
-        FwkException("Data not provided for 'regionName', failing.");
-      }
-      Region region = CacheHelper<TKey, TVal>.DCache.GetRegion(testRegionName);
-
-      int opsSecond = GetUIntValue("opsSecond");
-      if (opsSecond < 0)
-      {
-        opsSecond = 0; // No throttle
-      }
-      PaceMeter pm = new PaceMeter(opsSecond);
-
-      int secondsToRun = GetUIntValue("workTime");
-      secondsToRun = (secondsToRun < 1) ? 100 : secondsToRun;
-      FwkInfo("feedEntries: Will add entries for " + secondsToRun + " seconds.");
-      DateTime end = DateTime.Now + TimeSpan.FromSeconds((double)secondsToRun);
-      DateTime now = DateTime.Now;
-
-      int count = 0;
-      while (now < end)
-      {
-        string key = (++count).ToString();
-
-        // get value size
-        int vsize = GetUIntValue("valueSizes");
-        if (vsize < 0)
-        {
-          vsize = 1000;
-        }
-        byte[] buffer = new byte[vsize];
-        Util.RandBytes(buffer);
-
-        CacheableKey skey = new CacheableString(key);
-        Serializable value = CacheableBytes.Create(buffer);
-
-        if (key == null)
-        {
-          FwkSevere("EventTest::feedEntries null keyPtr generated.");
-          now = end;
-        }
-
-        region.Put(skey, value);
-        Util.BBIncrement(EventCountersBB, "CREATE_COUNT");
-        pm.CheckPace();
-        now = DateTime.Now;
-      }
-    }
-
-
-    public void doBasicTest()
-    {
-      Region region = GetRandomRegion(true);
-      int numKeys = GetUIntValue("distinctKeys");
-      numKeys = numKeys > 0 ? numKeys : 1000;
-      CacheableKey[] keys = new CacheableKey[numKeys];
-      Serializable[] values = new Serializable[numKeys];
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        int ksize = GetUIntValue("valueSizes");
-        ksize = ksize > 0 ? ksize : 12;
-        int vsize = GetUIntValue("valueSizes");
-        vsize = vsize > 0 ? vsize : 100;
-
-        string kStr = "key_";
-        byte[] buffer = new byte[vsize];
-        Util.RandBytes(buffer);
-        CacheableKey key = new CacheableString(kStr);
-        Serializable value = CacheableBytes.Create(buffer);
-        keys[i] = key;
-        values[i] = value;
-        region.Create(key, value);
-      }
-      ICacheableKey[] expectKeys = region.GetKeys();
-
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after create, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.LocalInvalidate(keys[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after localInvalidate, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        ISerializable val = region.Get(keys[i]);
-
-        if (val.ToString() != values[i].ToString())
-        {
-          FwkSevere("Expect " + values[i].ToString() + ", got " + val.ToString());
-        }
-      }
-
-      expectKeys = region.GetKeys();
-
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after first get, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.LocalDestroy(keys[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if ((expectKeys.Length) != 0)
-      {
-        FwkSevere("Expect 0 keys after localDestroy, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        ISerializable val = region.Get(keys[i]);         // get
-
-        if (val.ToString() != values[i].ToString())
-        {
-          FwkSevere("Expect " + values[i].ToString() + ", got " + val.ToString());
-        }
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after second get, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.Invalidate(keys[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after invalidate, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.Get(keys[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after invalidate all entries in server, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.Put(keys[i], values[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after put, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.Destroy(keys[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != 0)
-      {
-        FwkSevere("Expect 0 keys after destroy, got " + expectKeys.Length + " keys");
-      }
-
-      int excepCount = 0;
-      for (int i = 0; i < numKeys; ++i)
-      {
-        try
-        {
-          region.Get(keys[i]);
-        }
-        catch (EntryNotFoundException e)
-        {
-          FwkInfo(e.Message);
-          ++excepCount;
-        }
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != 0)
-      {
-        FwkSevere("Expect 0 keys because all entries are destoyed in server, got " + expectKeys.Length + " keys");
-      }
-
-      if (excepCount != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " exceptions because all entries are destoyed in server, got " + excepCount + " exceptions");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.Create(keys[i], values[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after second create, got " + expectKeys.Length + " keys");
-      }
-
-      for (int i = 0; i < numKeys; ++i)
-      {
-        region.Get(keys[i]);
-      }
-
-      expectKeys = region.GetKeys();
-      if (expectKeys.Length != numKeys)
-      {
-        FwkSevere("Expect " + numKeys + " keys after invalidate all entries in server, got " + expectKeys.Length + " keys");
-      }
-    }
-
-
-    public void doTwinkleRegion()
-    {
-      int secondsToRun = GetUIntValue("workTime");
-      secondsToRun = (secondsToRun < 1) ? 10 : secondsToRun;
-      FwkInfo("Seconds to run: " + secondsToRun);
-
-      int end = DateTime.Now.Second + secondsToRun;
-      bool done = false;
-      bool regionDestroyed = false;
-      int errCnt = 0;
-
-      while (!done)
-      {
-        int sleepTime = GetUIntValue("sleepTime");
-        sleepTime = ((sleepTime < 1) || regionDestroyed) ? 10 : sleepTime;
-        FwkInfo("sleepTime is " + sleepTime + " seconds.");
-
-        DateTime now = DateTime.Now;
-        // TODO: 10 magic number to avoid compilation
-        if ((now.Second > end) || ((now.Second + 10) > end))
-        {
-          // TODO : Check DateTime usage in the entire file.
-          // FWKINFO( "Exiting loop, time is up." );
-          done = true;
-          continue;
-        }
-
-        FwkInfo("EventTest::doTwinkleRegion() sleeping for " + sleepTime + " seconds.");
-        Thread.Sleep(sleepTime * 1000);
-
-        if (regionDestroyed)
-        {
-          FwkInfo("EventTest::doTwinkleRegion() will create a region.");
-          CreateRootRegion();
-          regionDestroyed = false;
-          FwkInfo("EventTest::doTwinkleRegion() region created.");
-          int percentDiff = percentDifferent();
-          if (percentDiff > 10)
-          {
-            errCnt++;
-            FwkSevere("Actual number of keys is not within 10% of expected.");
-          }
-        }
-        else
-        {
-          FwkInfo("EventTest::doTwinkleRegion() will destroy a region.");
-          Region region = GetRandomRegion(true);
-          if (region != null)
-          {
-            region.LocalDestroyRegion();
-            region = null;
-          }
-          regionDestroyed = true;
-          FwkInfo("EventTest::doTwinkleRegion() local region destroy is complete.");
-        }
-      } // while
-
-      if (regionDestroyed)
-      {
-        CreateRootRegion();
-        FwkInfo("EventTest::doTwinkleRegion() region created.");
-      }
-
-      FwkInfo("EventTest::doTwinkleRegion() completed.");
-      if (errCnt > 0)
-      {
-        FwkException("Region key count was out of bounds on " + errCnt + " region creates.");
-      }
-    }
-
-    // TODO Entire method check.
-    public void checkTest(string taskId)
-    {
-      // TODO: For lock
-      // SpinLockGuard guard( m_lck );
-      // TODO: setTask(taskId)
-      if (CacheHelper<TKey, TVal>.DCache == null)
-      {
-        Properties pp = new Properties();
-        //TODO: Initialize? cacheInitialize( pp );
-        //string val = getStringValue( "EventBB" );
-        //if ( !val.empty() )
-        //{
-        //  m_sEventBB = val;
-        //}
-
-      }
-    }
-
-    public void createRootRegion(string regionName)
-    {
-      FwkInfo("In createRootRegion region");
-      Region rootRegion;
-
-      if (regionName == null)
-      {
-        rootRegion = CreateRootRegion();
-      }
-      else
-      {
-        rootRegion = CacheHelper.CreateRegion(regionName, null);
-      }
-
-      Util.BBIncrement(EventCountersBB, rootRegion.FullPath);
-      Util.BBIncrement(EventCountersBB, "ROOT_REGION_COUNT");
-
-      FwkInfo("In createRootRegion, Created root region: " + rootRegion.FullPath);
-    }
-
-    public bool TestEntryPropagation(Region region, CacheableString szKey, CacheableBytes szValue)
-    {
-      bool bEntryError = false;
-      bool bContainsKey = false;
-      bool bContainsValue = false;
-
-      bContainsKey = region.ContainsKey(szKey);
-      bContainsValue = region.ContainsValueForKey(szKey);
-
-      if (!bContainsKey || !bContainsValue)
-      {
-        FwkSevere("Key: " + szKey.Value + " not found in region " +
-          region.FullPath + ", mirroring is enabled");
-        bEntryError = true;
-      }
-      return bEntryError;
-    }
-
-    public void addObject(Region region, bool bLogAddition, string pszKey, string pszValue)
-    {
-      CacheableKey key;
-      if (pszKey == null)
-      {
-        key = findKeyNotInCache(region);
-      }
-      else
-      {
-        key = new CacheableString(pszKey);
-      }
-
-      if (key == null)
-      {
-        FwkInfo("EventTest::addObject null key generated for " + pszKey);
-        return;
-      }
-
-      Serializable value;
-
-      if (pszValue == null)
-      {
-        int vsize = GetUIntValue("valueSizes");
-        if (vsize < 0)
-        {
-          vsize = 1000;
-        }
-        byte[] buffer = new byte[vsize];
-        Util.RandBytes(buffer);
-        value = CacheableBytes.Create(buffer);
-      }
-      else
-      {
-        value = new CacheableString(pszValue);
-      }
-
-      if (value == null)
-      {
-        FwkInfo("EventTest::addObject null valuePtr generated.");
-        return;
-      }
-
-      region.Create(key, value);
-      Util.BBIncrement(EventCountersBB, "CREATE_COUNT");
-    }
-
-    public void invalidateObject(Region randomRegion, bool bIsLocalInvalidate)
-    {
-      CacheableKey keyP = getKey(randomRegion, false);
-      if (keyP == null)
-      {
-        Util.BBIncrement(EventCountersBB, "OPS_SKIPPED_COUNT");
-        return;
-      }
-
-      if (bIsLocalInvalidate)
-      {
-        randomRegion.LocalInvalidate(keyP);
-        Util.BBIncrement(EventCountersBB, "LOCAL_INVALIDATE_COUNT");
-      }
-      else
-      {
-        randomRegion.Invalidate(keyP);
-        Util.BBIncrement(EventCountersBB, "INVALIDATE_COUNT");
-      }
-    }
-
-    public void destroyObject(Region randomRegion, bool bIsLocalDestroy)
-    {
-      FwkInfo("EventTest::destroyObject");
-
-      CacheableKey keyP = getKey(randomRegion, true);
-
-      if (keyP == null)
-      {
-        Util.BBIncrement(EventCountersBB, "OPS_SKIPPED_COUNT");
-        return;
-      }
-
-      if (bIsLocalDestroy)
-      {
-        randomRegion.LocalDestroy(keyP);
-        Util.BBIncrement(EventCountersBB, "LOCAL_DESTROY_COUNT");
-      }
-      else
-      {
-        randomRegion.Destroy(keyP);
-        Util.BBIncrement(EventCountersBB, "DESTROY_COUNT");
-      }
-    }
-
-    public void updateObject(Region randomRegion)
-    {
-      CacheableKey keyP = getKey(randomRegion, true);
-      if (keyP == null)
-      {
-        FwkInfo("EventTest::updateObject key is null");
-        Util.BBIncrement(EventCountersBB, "OPS_SKIPPED_COUNT");
-        return;
-      }
-
-      ISerializable anObj = randomRegion.Get(keyP);
-
-      int vsize = GetUIntValue("valueSizes");
-      if (vsize < 0)
-      {
-        vsize = 1000;
-      }
-
-      byte[] buffer = new byte[vsize];
-      Util.RandBytes(buffer);
-
-      CacheableBytes newObj = CacheableBytes.Create(buffer);
-
-      randomRegion.Put(keyP, newObj);
-    }
-
-    public void readObject(Region randomRegion)
-    {
-      FwkInfo("Inside readObject randomregion = {0}", randomRegion.FullPath);
-      CacheableKey keyP = getKey(randomRegion, true);
-
-      FwkInfo("After getkey");
-      if (keyP == null)
-      {
-        Util.BBIncrement(EventCountersBB, "OPS_SKIPPED_COUNT");
-        FwkInfo("skipped and returned");
-        return;
-      }
-      FwkInfo("skipped and returned before Get");
-      CacheableBytes anObj = randomRegion.Get(keyP) as CacheableBytes;
-      FwkInfo("got anobj");
-      //byte[] b = anObj.Value;
-      //FwkInfo("byte array = " + b.ToString());
-    }
-
-    public void addRegion()
-    {
-      Region parentRegion = null;
-      string sRegionName = getNextRegionName(parentRegion);
-      if (sRegionName.Length == 0)
-      {
-        // nothing to do
-        return;
-      }
-
-      Region region;
-      FwkInfo("In addRegion, enter create region " + sRegionName);
-      if (parentRegion == null)
-      {
-        // TODO Is this right.
-        region = CacheHelper.CreateRegion(sRegionName, null);
-      }
-      else
-      {
-
-        string fullName = parentRegion.FullPath;
-        var regionAttributes = parentRegion.Attributes;
-        var regionAttributesFactory = new AttributesFactory(regionAttributes);
-        regionAttributes = regionAttributesFactory.Create();
-        region = parentRegion.CreateSubRegion(sRegionName, regionAttributes);
-        Util.BBSet(EventCountersBB, sRegionName, fullName);
-      }
-
-      int iInitRegionNumObjects = GetUIntValue("initRegionNumObjects");
-      // Create objects in the new region
-      for (int iIndex = 0; iIndex < iInitRegionNumObjects; iIndex++)
-      {
-        string skey = iIndex.ToString();
-        addObject(region, true, skey, null);
-      }
-      FwkInfo("In addRegion, exit create region " + sRegionName);
-    }
-    public void clearRegion(Region randomRegion, bool bIsLocalClear)
-    {
-      int iSubRegionCount = 0;
-      // invalidate the region
-      iSubRegionCount = getSubRegionCount(randomRegion) + 1;
-
-      //bbGet("EventCountersBB", // TODO
-      //  "numAfterRegionInvalidateEvents_isNotExp", &iBeforeCounter);
-      FwkInfo("In clearRegion, enter clear region " + randomRegion.Name);
-
-      string pszCounterName = "LOCAL_REGION_CLEAR_COUNT";
-      if (bIsLocalClear)
-      {
-        randomRegion.LocalClear();
-      }
-      else
-      {
-        pszCounterName = "REGION_CLEAR_COUNT";
-        randomRegion.Clear();
-      }
-      Util.BBAdd(EventCountersBB, pszCounterName, iSubRegionCount);
-      FwkInfo("In clearRegion, exit invalidate region " + randomRegion.Name);
-    }
-
-    public void invalidateRegion(Region randomRegion, bool bIsLocalInvalidate)
-    {
-      int iSubRegionCount = 0;
-      // invalidate the region
-      iSubRegionCount = getSubRegionCount(randomRegion) + 1;
-
-      //bbGet("EventCountersBB", // TODO
-      //  "numAfterRegionInvalidateEvents_isNotExp", &iBeforeCounter);
-      FwkInfo("In invalidateRegion, enter invalidate region " + randomRegion.Name);
-
-      string pszCounterName = "LOCAL_REGION_INVALIDATE_COUNT";
-      if (bIsLocalInvalidate)
-      {
-        randomRegion.LocalInvalidateRegion();
-      }
-      else
-      {
-        pszCounterName = "REGION_INVALIDATE_COUNT";
-        randomRegion.InvalidateRegion();
-      }
-      Util.BBAdd(EventCountersBB, pszCounterName, iSubRegionCount);
-      FwkInfo("In invalidateRegion, exit invalidate region " + randomRegion.Name);
-    }
-
-    public void destroyRegion(Region randomRegion, bool bIsLocalDestroy)
-    {
-      int iSubRegionCount = 0;
-      // destroy the region
-      //int iBeforeCounter = -1;
-      //bbGet( "EventCountersBB", "numAfterRegionDestroyEvents_isNotExp", &iBeforeCounter );//TODO
-
-      iSubRegionCount = getSubRegionCount(randomRegion) + 1;
-      string pszCounterName = "LOCAL_REGION_DESTROY_COUNT";
-      FwkInfo("In destroyRegion, enter destroy region " + randomRegion.Name);
-      if (bIsLocalDestroy)
-      {
-        randomRegion.LocalDestroyRegion();
-      }
-      else
-      {
-        pszCounterName = "REGION_DESTROY_COUNT";
-        randomRegion.DestroyRegion();
-      }
-      Util.BBIncrement(EventCountersBB, pszCounterName);
-      FwkInfo("In destroyRegion, exit destroy region " + randomRegion.Name);
-    }
-
-    public Region GetRandomRegion(bool bAllowRootRegion)
-    {
-      FwkInfo("Inside GetRandomRegion ... Check 1");
-      Region[] rootRegionVector = CacheHelper<TKey, TVal>.DCache.RootRegions();
-      int irootSize = rootRegionVector.Length;
-
-      Region[] subRegionVector;
-      FwkInfo("Inside GetRandomRegion ... Check 2");
-      int iRootSize = rootRegionVector.Length;
-
-      if (iRootSize == 0)
-      {
-        // TODO
-        return null;
-        //return RegionPtr();
-      }
-      FwkInfo("Inside GetRandomRegion ... Check 3 and irrotsize = {0}", irootSize);
-      Region[] choseRegionVector = new Region[1];
-
-      // if roots can be chosen, add them to candidates
-      if (bAllowRootRegion)
-      {
-        for (int iRootIndex = 0; iRootIndex < iRootSize; iRootIndex++)
-        {
-          FwkInfo("Inside GetRandomRegion ... Check 4.{0}", iRootIndex);
-          choseRegionVector[iRootIndex] = rootRegionVector[iRootIndex];
-        }
-      }
-
-      FwkInfo("Inside GetRandomRegion ... Check 4");
-      // add all subregions
-      for (int iRootIndex = 0; iRootIndex < iRootSize; iRootIndex++)
-      {
-        subRegionVector = rootRegionVector[iRootIndex].SubRegions(true);
-        int iSubSize = subRegionVector.Length;
-        for (int iSubIndex = 0; iSubIndex < iSubSize; iSubIndex++)
-        {
-          choseRegionVector[choseRegionVector.Length] = subRegionVector[iSubIndex];
-          //choseRegionVector.push_back(subRegionVector.at(iSubIndex));
-        }
-      }
-
-      FwkInfo("Inside GetRandomRegion ... Check 5");
-      int iChoseRegionSize = choseRegionVector.Length;
-      if (iChoseRegionSize == 0)
-      {
-        // TODO
-        return null;
-        //return RegionPtr();
-      }
-
-      FwkInfo("Inside GetRandomRegion ... Check 6");
-      int idx = Util.Rand(iChoseRegionSize);
-      //string regionName = choseRegionVector.at(idx)->getFullPath();
-      FwkInfo("Inside GetRandomRegion ... Check 7");
-      return choseRegionVector[idx];
-    }
-
-
-    public void handleExpectedException(Exception e)
-    {
-      FwkInfo("Caught and ignored: " + e.Message);
-    }
-
-    public void verifyObjectInvalidated(Region region, CacheableKey key)
-    {
-      if ((region == null) && (key == null))
-      {
-        return;
-      }
-      string error = null;
-
-      if (!region.ContainsKey(key))
-      {
-        error = "unexpected contains key";
-      }
-
-      if (region.ContainsValueForKey(key))
-      {
-        error = "Unexpected containsValueForKey ";
-      }
-
-      RegionEntry entry = region.GetEntry(key);
-
-      if (entry == null)
-      {
-        error = "getEntry returned null";
-      }
-      else
-      {
-        if (entry.Key != key)
-        {
-          error = "Keys are different";
-        }
-
-        if (entry.Value != null)
-        {
-          error = "Expected value to be null";
-        }
-      }
-
-      if (error.Length != 0)
-      {
-        FwkException(error);
-      }
-    }
-
-    public void verifyObjectDestroyed(Region region, CacheableKey key)
-    {
-      if ((region == null) && (key == null))
-      {
-        return;
-      }
-
-      string osError;
-      bool bContainsKey = region.ContainsKey(key);
-      if (bContainsKey)
-      {
-        // TODO key.ToString()
-        osError = "Unexpected containsKey " + bContainsKey +
-        " for key " + key.ToString() + " in region " + region.FullPath +
-        Environment.NewLine;
-      }
-
-      bool bContainsValueForKey = region.ContainsValueForKey(key);
-      if (bContainsValueForKey)
-      {
-        osError = "Unexpected containsValueForKey " + bContainsValueForKey +
-          " for key " + key.ToString() + " in region " + region.FullPath +
-          Environment.NewLine;
-      }
-
-      RegionEntry entry = region.GetEntry(key);
-      // TODO ... see this section
-      //if (entry != null)
-      //{
-      //  CacheableString entryKey = key.;
-      //  CacheableBytes entryValuePtr = entryPtr->getValue();
-
-      //  osError << "getEntry for key " << CacheableStringPtr( keyPtr )->asChar() <<
-      //" in region " << regionPtr->getFullPath() <<
-      //" returned was non-null; getKey is " << entryKeyPtr->asChar() <<
-      //", value is " << entryValuePtr->bytes() << "\n";
-      //}
-
-      //if (sError.size() > 0)
-      //{
-      //  FWKEXCEPTION(sError);
-      //}
-    }
-
-
-    public void iterateRegion(Region aRegion, bool bAllowZeroKeys, bool bAllowZeroNonNullValues,
-      uint ulKeysInRegion, uint ulNoneNullValuesInRegion,
-      string sError)
-    {
-      if (aRegion == null)
-      {
-        return;
-      }
-
-      ulKeysInRegion = 0;
-      ulNoneNullValuesInRegion = 0;
-
-      ICacheableKey[] keyVector = aRegion.GetKeys();
-
-      ulKeysInRegion = (uint)keyVector.Length;
-      if (ulKeysInRegion == 0)
-      {
-        if (!bAllowZeroKeys)
-        {
-          sError = "Region " + aRegion.FullPath + " has " +
-            ulKeysInRegion + " keys" + Environment.NewLine;
-        }
-      }
-
-      CacheableKey key = null;
-      ISerializable value = null;
-
-      for (uint ulIndex = 0; ulIndex < ulKeysInRegion; ulIndex++)
-      {
-        key = keyVector[ulIndex] as CacheableKey;
-
-        try
-        {
-          value = aRegion.Get(key);
-        }
-        catch (CacheLoaderException e)
-        {
-          FwkException("CacheLoaderException " + e.Message);
-        }
-        catch (TimeoutException e)
-        {
-          FwkException("TimeoutException " + e.Message);
-        }
-
-        if (value != null)
-        {
-          ulNoneNullValuesInRegion++;
-        }
-      }
-
-      if (ulNoneNullValuesInRegion == 0)
-      {
-        if (!bAllowZeroNonNullValues)
-        {
-          sError += "Region " + aRegion.FullPath + " has " +
-            ulNoneNullValuesInRegion + " non-null values" + Environment.NewLine;
-        }
-      }
-    }
-
-
-    public int getSubRegionCount(Region region)
-    {
-      Region[] subregions = region.SubRegions(true);
-      return subregions.Length;
-    }
-
-    public int getAllRegionCount()
-    {
-      if (CacheHelper<TKey, TVal>.DCache == null)
-      {
-        FwkSevere("Null cache pointer, no connection established.");
-        return 0;
-      }
-      Region[] rootRegions = CacheHelper<TKey, TVal>.DCache.RootRegions();
-      int iRootSize = rootRegions.Length;
-      int iTotalRegions = iRootSize;
-
-      for (int iIndex = 0; iIndex < iRootSize; iIndex++)
-      {
-        // TODO getSubRegionCount implementation
-        iTotalRegions += getSubRegionCount(rootRegions[iIndex]);
-      }
-      return iTotalRegions;
-    }
-
-    public CacheableKey getKey(Region region, bool bInvalidOK)
-    {
-      FwkInfo("random key check 1");
-      //int randomKey = int.Parse((string)Util.ReadObject("randomKey"));
-      int randomKey = GetUIntValue("randomKey");
-      CacheableKey keyP = null;
-      FwkInfo("random key check 2 ... randomkey = {0}", randomKey);
-      if (randomKey > 0)
-      {
-        string sKey = randomKey.ToString();
-        keyP = new CacheableString(sKey);
-        FwkInfo("random key check 2.1 .. keyP.tostring = {0}", keyP.ToString());
-        return keyP;
-      }
-      FwkInfo("random key check 3");
-
-      ICacheableKey[] keys = region.GetKeys();
-      int iKeySize = keys.Length;
-      if (iKeySize == 0)
-      {
-        return keyP;
-      }
-      FwkInfo("random key check 4");
-      int iStartAt = Util.Rand(iKeySize);
-      if (bInvalidOK)
-      {
-        return keys[iStartAt] as CacheableKey;
-      }
-      int iKeyIndex = iStartAt;
-      do
-      {
-        FwkInfo("random key check 5");
-        bool hasValue = region.ContainsValueForKey(keys[iKeyIndex]);
-        if (hasValue)
-        {
-          return keys[iKeyIndex] as CacheableKey;
-        }
-        iKeyIndex++;
-        if (iKeyIndex >= iKeySize)
-        {
-          iKeyIndex = 0;
-        }
-      } while (iKeyIndex != iStartAt);
-
-      FwkInfo("getKey: All values invalid in region");
-      return keyP;
-    }
-
-    public void setEventError(string pszMsg)
-    {
-      Util.BBSet(EventCountersBB, "EventErrorMessage", pszMsg);
-    }
-
-    public void removeRegion(Region region)
-    {
-      string name = region.FullPath;
-      FwkInfo("In removeRegion, local destroy on " + name);
-      region.LocalDestroyRegion();
-      Util.BBDecrement(EventCountersBB, name);
-    }
-
-    public Int32 getRegionCount()
-    {
-      FwkInfo("Check 1.1 Inside getRegionCount");
-      Region[] roots = CacheHelper<TKey, TVal>.DCache.RootRegions();
-      FwkInfo("Check 1.1 root region count = {0}", roots.Length);
-      return roots.Length;
-    }
-
-    #endregion
-
-    #region Callback create methods
-    public static ICacheWriter CreateETCacheWriter()
-    {
-      return new ETCacheWriter();
-    }
-    public static ICacheLoader CreateETCacheLoader()
-    {
-      return new ETCacheLoader();
-    }
-
-    public static ICacheListener CreateETCacheListener()
-    {
-      return new ETCacheListener();
-    }
-
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/FunctionExecution/FunctionExecution.cs b/tests/cli/NewFwkLib/FunctionExecution/FunctionExecution.cs
deleted file mode 100644
index 552637c..0000000
--- a/tests/cli/NewFwkLib/FunctionExecution/FunctionExecution.cs
+++ /dev/null
@@ -1,1375 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-
-    //----------------------------------- DoOpsTask start ------------------------
-    public class DoFETask<TKey, TVal> : ClientTask
-    {
-        private IRegion<TKey, TVal> m_region;
-        private const int INVALIDATE = 1;
-        private const int LOCAL_INVALIDATE = 2;
-        private const int DESTROY = 3;
-        private const int LOCAL_DESTROY = 4;
-        private const int UPDATE_EXISTING_KEY = 5;
-        private const int GET = 6;
-        private const int ADD_NEW_KEY = 7;
-        private const int PUTALL_NEW_KEY = 8;
-        //private const int QUERY = 8;
-        private const int NUM_EXTRA_KEYS = 100;
-        private static bool m_istransaction = false;
-        private static string m_funcName;
-        CacheTransactionManager txManager = null;
-        private object CLASS_LOCK = new object();
-        private object SKIPS_LOCK = new object();
-        protected int[] operations = { INVALIDATE, LOCAL_INVALIDATE, DESTROY, LOCAL_DESTROY, UPDATE_EXISTING_KEY, GET, ADD_NEW_KEY, PUTALL_NEW_KEY };
-        public DoFETask(IRegion<TKey, TVal> region, bool istransaction)
-            : base()
-        {
-            m_region = region;
-            m_istransaction = istransaction;
-            m_funcName = FwkTest<TKey, TVal>.CurrentTest.GetStringValue("funcName");
-
-        }
-        public override void DoTask(int iters, object data)
-        {
-
-            Random random = new Random();
-            List<int> availableOps = new List<int>(operations);
-            lock (SKIPS_LOCK)
-            {
-                FwkTest<TKey, TVal>.CurrentTest.ResetKey("isSkipOps");
-                bool isSkipOps = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isSkipOps");
-                if (isSkipOps)
-                {
-                    availableOps.Remove(LOCAL_INVALIDATE);
-                    availableOps.Remove(LOCAL_DESTROY);
-                   
-                }
-            }
-            while (Running && (availableOps.Count != 0))
-            {
-                int opcode = -1;
-                lock (CLASS_LOCK)
-                {
-                    bool doneWithOps = false;
-                    int i = random.Next(0, availableOps.Count);
-                    try
-                    {
-                        opcode = availableOps[i];
-                        if (m_istransaction)
-                        {
-                            txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-                            txManager.Begin();
-                        }
-                        switch (opcode)
-                        {
-                            case ADD_NEW_KEY:
-                                doneWithOps = addNewKeyFunction();
-                                break;
-                            /*case QUERY:
-                                doneWithOps = queryFunction();
-                                break;*/
-                            case PUTALL_NEW_KEY:
-                                doneWithOps = putAllNewKeyFunction();
-                                break;
-                            case INVALIDATE:
-                                doneWithOps = invalidateFunction();
-                                break;
-                            case DESTROY:
-                                doneWithOps = destroyFunction();
-                                break;
-                            case UPDATE_EXISTING_KEY:
-                                doneWithOps = updateExistingKeyFunction();
-                                break;
-                            case GET:
-                                doneWithOps = getFunction();
-                                break;
-                            case LOCAL_INVALIDATE:
-                                doneWithOps = localInvalidateFunction();
-                                break;
-                            case LOCAL_DESTROY:
-                                doneWithOps = localDestroyFunction();
-                                break;
-                            default:
-                                {
-                                    throw new Exception("Invalid operation specified:" + opcode);
-                                }
-                        }
-                        if (m_istransaction && (txManager != null) && (!doneWithOps))
-                        {
-                            try
-                            {
-                                txManager.Commit();
-                            }
-                            catch (CommitConflictException)
-                            {
-                                // can occur with concurrent execution
-                                Util.Log("Caught CommitConflictException. Expected with concurrent execution, continuing test.");
-                            }
-                            catch (TransactionDataNodeHasDepartedException e)
-                            {
-                                FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught TransactionDataNodeHasDepartedException in doEntry : {0}", e);
-                            }
-                            catch (Exception ex)
-                            {
-                                FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught unexpected in doEntry : {0}", ex);
-                            }
-                        }
-                    }
-                    catch (TimeoutException e)
-                    {
-                        FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught unexpected timeout exception during entry operation: " + opcode + " " + e);
-                    }
-                    catch (IllegalStateException e)
-                    {
-                        FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught IllegalStateException during entry operation:" + opcode + " " + e);
-                    }
-                    catch (Exception e)
-                    {
-                        FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught exception during entry operation: " + opcode + "  exiting task.\n" + e);
-                    }
-                    if (doneWithOps)
-                    {
-                        if (m_istransaction && txManager != null)
-                        {
-                            try
-                            {
-                                txManager.Rollback();
-                            }
-                            catch (IllegalStateException e)
-                            {
-                                FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught IllegalStateException during rollback: " + e);
-                            }
-                            catch (Exception e)
-                            {
-                                FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught exception during entry operation: " + e + " exiting task.\n");
-                            }
-                        }
-                        availableOps.Remove(opcode);
-                    }
-                }
-            }
-        } //end doTask function
-       
-        private void checkContainsValueForKey(TKey key, bool expected, string logStr)
-        {
-            //RegionPtr regionPtr = getRegion();
-            bool containsValue = m_region.ContainsValueForKey(key);
-            if (containsValue != expected)
-                FwkTest<TKey, TVal>.CurrentTest.FwkException("DoOpsTask::checkContainsValueForKey: Expected containsValueForKey(" + key + ") to be " + expected +
-                         ", but it was " + containsValue + ": " + logStr);
-        }
-        
-        bool addNewKeyFunction()
-        {
-            int numNewKeysCreated = (int)Util.BBGet("ImageBB", "NUM_NEW_KEYS_CREATED");
-            Util.BBIncrement("ImageBB", "NUM_NEW_KEYS_CREATED");
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("NumNewKeys");
-            int numNewKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("NumNewKeys");
-            if (numNewKeysCreated > numNewKeys)
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All new keys created; returning from addNewKey");
-                return true;
-            }
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("entryCount");
-            int entryCount = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("entryCount");
-            entryCount = (entryCount < 1) ? 10000 : entryCount;
-            TKey key = (TKey)(object)(entryCount + numNewKeysCreated);
-            checkContainsValueForKey(key, false, "before addNewKey");
-
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("isPdxObject");
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("addKey");
-            if (pdxobject)
-                args.Add(pdxobject);    
-            args.Add(filterObj[0]); 
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do addKey execute");
-            ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "addNewKeyFunction");
-            return (numNewKeysCreated >= numNewKeys);
-        }
-        bool putAllNewKeyFunction()
-        {
-            int numNewKeysCreated = (int)Util.BBGet("ImageBB", "NUM_NEW_KEYS_CREATED");
-            Util.BBIncrement("ImageBB", "NUM_NEW_KEYS_CREATED");
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("NumNewKeys");
-            int numNewKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("NumNewKeys");
-            if (numNewKeysCreated > numNewKeys)
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All new keys created; returning from addNewKey");
-                return true;
-            }
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("entryCount");
-            int entryCount = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("entryCount");
-            entryCount = (entryCount < 1) ? 10000 : entryCount;
-            TKey key = (TKey)(object)(entryCount + numNewKeysCreated);
-            if(m_region.Attributes.CloningEnabled != false)
-              checkContainsValueForKey(key, false, "before addNewKey");
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("isPdxObject");
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("putAll");
-            if (pdxobject)
-                args.Add(pdxobject);
-            args.Add(filterObj[0]);
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do addKey execute");
-            ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "putAllNewKeyFunction");
-            return (numNewKeysCreated >= numNewKeys);
-        }
-        bool invalidateFunction()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_INVALIDATE");
-            Util.BBIncrement("ImageBB", "LASTKEY_INVALIDATE");
-            int firstKey = (int)Util.BBGet("ImageBB", "First_Invalidate");
-            int lastKey = (int)Util.BBGet("ImageBB", "Last_Invalidate");
-            if (!((nextKey >= firstKey) && (nextKey <= lastKey)))
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All existing keys invalidated; returning from invalidate");
-                return true;
-            }
-            TKey key = (TKey)(object)(nextKey);
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("invalidate");
-            if(pdxobject)
-                args.Add(pdxobject);      
-            args.Add(filterObj[0]); 
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do invalidate execute");
-             ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "invalidateFunction");
-            return (nextKey >= lastKey);
-        }
-        bool localInvalidateFunction()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_LOCAL_INVALIDATE");
-            Util.BBIncrement("ImageBB", "LASTKEY_LOCAL_INVALIDATE");
-            int firstKey = (int)Util.BBGet("ImageBB", "First_LocalInvalidate");
-            int lastKey = (int)Util.BBGet("ImageBB", "Last_LocalInvalidate");
-            if (!((nextKey >= firstKey) && (nextKey <= lastKey)))
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All local invalidates completed; returning from localInvalidate");
-                return true;
-            }
-            TKey key = (TKey)(object)(nextKey);
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("localinvalidate");
-            if (pdxobject)
-                args.Add(pdxobject);
-            args.Add(filterObj[0]); 
-            
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do locally invalidate execute");
-             ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "localInvalidateFunction");
-            return (nextKey >= lastKey);
-        }
-        bool destroyFunction()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_DESTROY");
-            Util.BBIncrement("ImageBB", "LASTKEY_DESTROY");
-            int firstKey = (int)Util.BBGet("ImageBB", "First_Destroy");
-            int lastKey = (int)Util.BBGet("ImageBB", "Last_Destroy");
-            if (!((nextKey >= firstKey) && (nextKey <= lastKey)))
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All destroys completed; returning from destroy");
-                return true;
-            }
-            TKey key = (TKey)(object)(nextKey);
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("destroy");
-            if (pdxobject)
-                args.Add(pdxobject);
-            args.Add(filterObj[0]); 
-           
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do destroy execute");
-             ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "destroyFunction");
-            return (nextKey >= lastKey);
-        }
-        bool localDestroyFunction()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_LOCAL_DESTROY");
-            Util.BBIncrement("ImageBB", "LASTKEY_LOCAL_DESTROY");
-            int firstKey = (int)Util.BBGet("ImageBB", "First_LocalDestroy");
-            int lastKey = (int)Util.BBGet("ImageBB", "Last_LocalDestroy");
-            if (!((nextKey >= firstKey) && (nextKey <= lastKey)))
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All local destroys completed; returning from localDestroy");
-                return true;
-            }
-            TKey key = (TKey)(object)(nextKey);
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("localdestroy");
-            if (pdxobject)
-                args.Add(pdxobject);
-            args.Add(filterObj[0]); 
-           
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do local destroy execute");
-             ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "localDestroyFunction");
-            return (nextKey >= lastKey);
-        }
-        bool updateExistingKeyFunction()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_UPDATE_EXISTING_KEY");
-            Util.BBIncrement("ImageBB", "LASTKEY_UPDATE_EXISTING_KEY");
-            int firstKey = (int)Util.BBGet("ImageBB", "First_UpdateExistingKey");
-            int lastKey = (int)Util.BBGet("ImageBB", "Last_UpdateExistingKey");
-            if (!((nextKey >= firstKey) && (nextKey <= lastKey)))
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All existing keys updated; returning from updateExistingKey");
-                return true;
-            }
-            TKey key = (TKey)(object)(nextKey);
-
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("isPdxObject");
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("update");
-            if (pdxobject)
-                args.Add(pdxobject);
-            args.Add(filterObj[0]); 
-            
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do update execute");
-             ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "updateExistingKeyFunction");
-            return (nextKey >= lastKey);
-        }
-        bool getFunction()
-        {
-            int nextKey = (int)Util.BBGet("ImageBB", "LASTKEY_GET");
-            Util.BBIncrement("ImageBB", "LASTKEY_GET");
-            int firstKey = (int)Util.BBGet("ImageBB", "First_Get");
-            int lastKey = (int)Util.BBGet("ImageBB", "Last_Get");
-            if (!((nextKey >= firstKey) && (nextKey <= lastKey)))
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All gets completed; returning from get");
-                return true;
-            }
-            TKey key = (TKey)(object)(nextKey);
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("isPdxObject");
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("get");
-            if (pdxobject)
-                args.Add(pdxobject);
-            args.Add(filterObj[0]); 
-            
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do get execute");
-             ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "getFunction");
-            return (nextKey >= lastKey);
-        }
-        bool queryFunction()
-        {
-            int numNewKeysCreated = (int)Util.BBGet("ImageBB", "NUM_NEW_KEYS_CREATED");
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("NumNewKeys");
-            int numThread = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("numThreads");
-            numNewKeysCreated = numNewKeysCreated - (numThread - 1);
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("NumNewKeys");
-            int numNewKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("NumNewKeys");
-            if (numNewKeysCreated > numNewKeys)
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("All query executed; returning from addNewKey");
-                return true;
-            }
-            int entryCount = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("entryCount");
-            entryCount = (entryCount < 1) ? 10000 : entryCount;
-            TKey key = (TKey)(object)(entryCount + numNewKeysCreated);
-            checkContainsValueForKey(key, false, "before addNewKey");
-            //TVal value = GetValue((TVal)(object)(entryCount + numNewKeysCreated));
-            //GetValue(value);
-            //m_region.Add(key, value);
-            Object[] filterObj = new Object[1];
-            filterObj[0] = (TKey)(object)key;
-            ArrayList args = new ArrayList();
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("isPdxObject");
-            bool pdxobject = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("isPdxObject");
-            args.Add("query");
-            if (pdxobject)
-                args.Add(pdxobject);
-            args.Add(filterObj[0]); 
-            
-            Apache.Geode.Client.Execution<object> exc =
-                Client.FunctionService<object>.OnRegion<TKey, TVal>(m_region);
-            //FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Going to do query execute");
-             ICollection<object> executeFunctionResult = null;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("replicated");
-            bool isReplicate = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("replicated");
-            if (!isReplicate){
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<object>(filterObj).Execute(m_funcName).GetResult(); 
-            }else
-            {
-                executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(m_funcName).GetResult();      
-            }
-            verifyFEResult(executeFunctionResult, "queryFunction");
-            return (numNewKeysCreated >= numNewKeys);
-        }
-        private void verifyFEResult(ICollection<object> exefuncResult, string funcName)
-        {
-            if (exefuncResult != null)
-            {
-                foreach (object item in exefuncResult)
-                {
-                    if ((bool)item != true)
-                    {
-                        FwkTest<TKey, TVal>.CurrentTest.FwkException("DoFETask::" + funcName + "failed, last result is not true");
-                    }
-                }
-            }
-        }
-           
-    }
-
-    //------------------------------------DoOpsTask end --------------------------
-
-
-  public class FunctionExecution<TKey,TVal> : FwkTest<TKey, TVal>
-
-  {
-    private const int NUM_EXTRA_KEYS = 100;
-    private static bool m_istransaction = false;
-    private static List<TKey> destroyedKeys = new List<TKey>();
-    protected IRegion<TKey,TVal> GetRegion()
-    {
-      return GetRegion(null);
-    }
-
-    protected IRegion<TKey,TVal> GetRegion(string regionName)
-    {
-      IRegion<TKey, TVal> region;
-      if (regionName == null)
-      {
-        region = GetRootRegion();
-        if (region == null)
-        {
-          IRegion<TKey, TVal>[] rootRegions = CacheHelper<TKey, TVal>.DCache.RootRegions<TKey, TVal>();
-         
-          if (rootRegions != null && rootRegions.Length > 0)
-          {
-            region = rootRegions[Util.Rand(rootRegions.Length)];
-          }
-        }
-      }
-      else
-      {
-        region = CacheHelper<TKey, TVal>.GetRegion(regionName);
-      }
-      return region;
-    }
-    public virtual void DoCreateRegion()
-    {
-      FwkInfo("In DoCreateRegion()");
-      try
-      {
-        IRegion<TKey, TVal> region = CreateRootRegion();
-        ResetKey("useTransactions");
-        m_istransaction = GetBoolValue("useTransactions");
-        if (region == null)
-        {
-          FwkException("DoCreateRegion()  could not create region.");
-        }
-        FwkInfo("DoCreateRegion()  Created region '{0}'", region.Name);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreateRegion() complete.");
-    }
-    public void DoCloseCache()
-    {
-      FwkInfo("DoCloseCache()  Closing cache and disconnecting from" +
-        " distributed system.");
-      CacheHelper<TKey, TVal>.Close();
-    }
-      public virtual void DoClearRegion()
-      {
-          FwkInfo("In DoClearRegion()");
-          try
-          {
-              IRegion<TKey, TVal> region = GetRegion();
-              region.Clear();
-          }
-          catch (Exception ex)
-          {
-              FwkException("DoClearRegion() Caught Exception: {0}", ex);
-          }
-          FwkInfo("DoClearRegion() complete.");
-      }
-    public void DoLoadRegion()
-    {
-      FwkInfo("In DoLoadRegion()");
-      try
-      {
-       IRegion<TKey, TVal> region = GetRegion();
-        ResetKey("distinctKeys");
-        int numKeys = GetUIntValue("distinctKeys");
-        bool isUpdate = GetBoolValue("update");
-        //string key = null;
-        //string value = null;
-        TKey key;
-        TVal value;
-        for (int j = 1; j < numKeys; j++)
-        {
-          string k = "key-" + j;
-          string v = null;
-          key = (TKey)(object)(k.ToString());
-          if (isUpdate)
-          {
-            v = "valueUpdate-" + j;
-            value = (TVal)(object)(v.ToString());
-          }
-          else
-          {
-            v = "valueCreate-" + j;
-            value = (TVal)(object)(v.ToString());
-          }
-         // region.Put(key, value);
-          region[key] = value;
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoLoadRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoLoadRegion() complete.");
-    }
-    public void DoAddDestroyNewKeysFunction()
-    {
-      FwkInfo("In DoAddDestroyNewKeysFunction()");
-      IRegion<TKey, TVal> region = GetRegion();
-      ResetKey("distinctKeys");
-      Int32 numKeys = GetUIntValue("distinctKeys");
-      int clientNum = Util.ClientNum;
-      //ISerializable[] filterObj = new ISerializable[numKeys];
-      Object[] filterObj = new Object[numKeys];
-      try
-      {
-        for(int j = 0; j < numKeys; j++)
-        {
-          //filterObj[j] = new CacheableString("KEY--" + clientNum + "--" + j);
-          filterObj[j] = "KEY--" + clientNum + "--" + j;
-        }
-        string opcode = GetStringValue( "entryOps" );
-        if(opcode == "destroy")
-          ExecuteFunction(filterObj, "destroy");
-        else
-          ExecuteFunction(filterObj,"addKey");
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoAddDestroyNewKeysFunction() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoAddDestroyNewKeysFunction() complete.");
-    }
-    private void ExecuteFunction(Object[] filterObj, string ops)
-    {
-      FwkInfo("In ExecuteFunction() ops is {0}", ops);
-      try
-      {
-        ResetKey( "getResult" );
-        Boolean getresult = GetBoolValue("getResult");
-        ResetKey( "replicated" );
-        bool isReplicate = GetBoolValue("replicated");
-        ResetKey( "distinctKeys" );
-        Int32 numKeys = GetUIntValue( "distinctKeys" );
-       // CacheableVector args = new CacheableVector();
-        ArrayList args = new ArrayList();
-        if (filterObj == null)
-        {
-          int clntId = Util.ClientNum;
-          filterObj = new Object[1];
-          //filterObj = new ISerializable[1];
-          Random rnd = new Random();
-          //filterObj[0] = new CacheableString("KEY--" + clntId + "--" + rnd.Next(numKeys));
-          filterObj[0] = "KEY--" + clntId + "--" + rnd.Next(numKeys);
-          args.Add(filterObj[0]);
-        }
-        else
-        {
-          for (int i = 0; i < filterObj.Length; i++)
-          {
-            args.Add(filterObj[i]);
-          }
-        }
-        if (ops.Equals("destroy"))
-        {
-          for (int i = 0; i < filterObj.Length; i++)
-          {
-            destroyedKeys.Add((TKey)filterObj[i]);
-          }
-        }
-        //Execution<object> exc = null;
-        Apache.Geode.Client.Execution<object> exc = null;
-        //Execution exc = null;
-        Pool/*<TKey, TVal>*/ pptr = null;
-        IRegion<TKey, TVal> region = GetRegion();
-        ResetKey("executionMode");
-        string executionMode = GetStringValue( "executionMode" );
-        ResetKey("poolName");
-        string poolname = GetStringValue( "poolName" );
-        string funcName = null;
-        if(executionMode == "onServers" || executionMode  == "onServer"){
-          pptr = CacheHelper<TKey, TVal>.DCache.GetPoolManager().Find(poolname);
-          if(getresult)
-            funcName = "ServerOperationsFunction";
-          else
-            funcName = "ServerOperationsWithOutResultFunction";
-        }
-        if ( executionMode == "onServers") {
-          /*exc = Client.FunctionService.OnServers<TKey,TVal,object>(pptr);*/
-          exc = Client.FunctionService<object>.OnServers(pptr);
-        } if ( executionMode == "onServer"){
-          exc = Client.FunctionService<object>.OnServer(pptr);
-        }else if( executionMode == "onRegion"){
-          exc = Client.FunctionService<object>.OnRegion<TKey, TVal>(region);
-          if(getresult)
-            funcName = "RegionOperationsFunction";
-          else
-            funcName = "RegionOperationsWithOutResultFunction";
-        }
-        //FwkInfo("ExecuteFunction - function name is{0} ", funcName);
-        //ISerializable[] executeFunctionResult = null;
-        ICollection<object> executeFunctionResult = null;
-        if(!isReplicate){
-          if(getresult == true){
-            if(executionMode == "onRegion"){
-              executeFunctionResult = exc.WithArgs<string>(ops).WithFilter<object>(filterObj).Execute(funcName, TimeSpan.FromSeconds(15)).GetResult();
-            }else{
-              args.Add(ops);
-              executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(funcName, TimeSpan.FromSeconds(15)).GetResult();
-            }
-          }else {
-            if(executionMode == "onRegion"){
-              exc.WithArgs<string>(ops).WithFilter<object>(filterObj).Execute(funcName, TimeSpan.FromSeconds(15));
-            } else {
-              args.Add(ops);
-              exc.WithArgs<ArrayList>(args).Execute(funcName, TimeSpan.FromSeconds(15));
-            }
-          }
-        } else {
-          args.Add(ops);
-          if (getresult)
-          {
-            executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(funcName, TimeSpan.FromSeconds(15)).GetResult();
-          }
-          else
-          {
-            executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(funcName, TimeSpan.FromSeconds(15)).GetResult();
-          }       
-        }
-        Thread.Sleep(30000);
-        if (ops == "addKey")
-        {
-          VerifyAddNewResult(executeFunctionResult, filterObj);
-        }
-        else
-        {
-          VerifyResult(executeFunctionResult, filterObj, ops);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("ExecuteFunction() Caught Exception: {0}", ex);
-      }
-      FwkInfo("ExecuteFunction() complete.");
-    }
-    public void VerifyAddNewResult(ICollection<object> exefuncResult, Object[] filterObj)
-    {
-      FwkInfo("In VerifyAddNewResult()");
-      try
-      {
-        Thread.Sleep(30000);
-        IRegion<TKey, TVal> region = GetRegion();
-        //CacheableString value = null;
-        string value = null;
-        if (filterObj != null)
-        {
-          for (int i = 0; i < filterObj.Length; i++)
-          {
-           // CacheableKey key = filterObj[i] as CacheableKey;
-            TKey key = (TKey)filterObj[i];
-            for (int cnt = 0; cnt < 100; cnt++)
-            {
-             // value = region.Get(key) as CacheableString;
-              value = region[key].ToString();
-            }
-            //CacheableString expectedVal = filterObj[i] as CacheableString;
-            string expectedVal = (String)filterObj[i];
-            if (!(expectedVal.Equals(value)))
-            {
-              FwkException("VerifyAddNewResult Failed: expected value is {0} and found {1} for key {2}", expectedVal, value, key.ToString());
-            }
-          }
-        }
-      }
-      catch (Apache.Geode.Client.KeyNotFoundException ex)
-      {
-        FwkInfo("VerifyAddNewResult() caught exception: {0}", ex);
-      }
-      catch (Exception ex)
-      {
-        FwkException("VerifyAddNewResult() Caught Exception: {0}", ex);
-      }
-      FwkInfo("VerifyAddNewResult() complete.");
-    }
-    public void VerifyResult(ICollection<object> exefuncResult, Object[] filterObj, string ops)
-    {
-      FwkInfo("In VerifyResult()");
-      Boolean getresult = GetBoolValue("getResult");
-      FwkInfo("In VerifyResult() getresult = {0} ", getresult);
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        string buf = null;
-        if(exefuncResult != null)
-        {
-          IEnumerator<object> enm = exefuncResult.GetEnumerator();
-          enm.MoveNext();
-          Boolean lastResult = (Boolean)enm.Current; //exefuncResult[0];
-          if (lastResult!= true)
-          FwkException("FunctionExecution::VerifyResult failed, last result is not true");
-        }
-        string value = null;
-        if(filterObj != null )
-        {
-            //CacheableKey key = filterObj[0] as CacheableKey;
-            TKey key = (TKey)filterObj[0];
-            for (int i = 0; i<50;i++){
-              try
-              {
-                value = region[key].ToString();
-              }
-              catch (Apache.Geode.Client.KeyNotFoundException)
-              {
-                if(ops.Equals("destroy") && destroyedKeys.Remove(key))
-                {
-                  FwkInfo("FunctionExecution.VerifyResults() key {0} has been destroyed " +
-                " in read for index {1} ", key,i);
-                  break;
-                }
-                else
-                {
-                  if (getresult)
-                  {
-                    FwkException("FunctionExecution.VerifyResults() Caught KeyNotFoundException " +
-                      " in read for key: {0} for index {1}", key, i);
-                  }
-                  else
-                  {
-                    FwkInfo("FunctionExecution.VerifyResults() key {0} Caught KeyNotFoundException for getResult false" +
-                      " in read for index {1} ", key, i);
-                    break;
-                  }
-                }
-              }
-            }
-            if(ops == "update" || ops == "get"){
-              if (value != null)
-              {
-                if (value.IndexOf("update_") == 0)
-                  buf = "update_" + key.ToString();
-                else
-                  buf = key.ToString();
-                  if (!(buf.Equals(value)))
-                    FwkException("VerifyResult Failed: expected value is {0} and found {1} for key {2} for operation {3}", buf, value, key.ToString(), ops);
-              }
-            } else if(ops == "destroy"){
-                if(value == null){
-                  ExecuteFunction(filterObj,"addKey");
-                }else{
-                  FwkException("FunctionExecution::VerifyResult failed to destroy key {0}",key.ToString());
-                }
-            } else if(ops == "invalidate"){
-              if(value == null)
-              {
-                ExecuteFunction(filterObj,"update");
-              }else {
-                FwkException("FunctionExecution::VerifyResult Failed for invalidate key {0}" ,key.ToString());
-              }
-            }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("VerifyResult() Caught Exception: {0}", ex);
-      }
-      FwkInfo("VerifyResult() complete.");
-    }
-    public void DoExecuteFunctions()
-    {
-      FwkInfo("In DoExecuteFunctions()");
-      int secondsToRun = GetTimeValue("workTime");
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-      string opcode = null;
-      bool rolledback = false;
-      CacheTransactionManager txManager = null;
-      while (now < end)
-      {
-        try
-        {
-          if (m_istransaction)
-          {
-            txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-            txManager.Begin();
-          }
-          opcode = GetStringValue("entryOps");
-          ExecuteFunction(null, opcode);
-          if (m_istransaction && !rolledback)
-          {
-            try
-            {
-              txManager.Commit();
-            }
-            catch (CommitConflictException)
-            {
-              // can occur with concurrent execution
-              Util.Log("Caught CommitConflictException. Expected with concurrent execution, continuing test.");
-            }
-            catch (Exception ex)
-            {
-              throw new Exception("Caught unexpected in doEntry : {0}", ex);
-            }
-          }
-        }
-        catch (Exception ex)
-        {
-          FwkException("DoExecuteFunctions() Caught Exception: {0}", ex);
-        }
-        now = DateTime.Now;
-      }
-      FwkInfo("DoExecuteFunctions() complete.");
-    }
-    public void DoExecuteExceptionHandling()
-    {
-      FwkInfo("In DoExecuteExceptionHandling()");
-      int secondsToRun = GetTimeValue("workTime");
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-      string opcode = null;
-      bool rolledback = false;
-      CacheTransactionManager txManager = null;
-      while (now < end)
-      {
-        try
-        {
-          if (m_istransaction)
-          {
-            txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-            txManager.Begin();
-          }
-          opcode = GetStringValue("entryOps");
-          if(opcode == "ParitionedRegionFunctionExecution")
-          {
-            DoParitionedRegionFunctionExecution();
-          }
-          else if (opcode == "ReplicatedRegionFunctionExecution")
-          {
-            DoReplicatedRegionFunctionExecution();
-          }
-          else if (opcode == "FireAndForgetFunctionExecution")
-          {
-            DoFireAndForgetFunctionExecution();
-          }
-          else if (opcode == "OnServersFunctionExcecution")
-          {
-            DoOnServersFunctionExcecution();
-          }
-          if (m_istransaction && !rolledback)
-          {
-            try
-            {
-              txManager.Commit();
-            }
-            catch (CommitConflictException)
-            {
-              // can occur with concurrent execution
-              Util.Log("Caught CommitConflictException. Expected with concurrent execution, continuing test.");
-            }
-            catch (Exception ex)
-            {
-              throw new Exception("Caught unexpected in doEntry : {0}", ex);
-            }
-          }
-        }
-        catch (Exception ex)
-        {
-          FwkException( "Caught unexpected {0} during exception handling for {1} operation: {2} : exiting task." ,ex.ToString(), opcode,ex.Message);
-
-        }
-        now = DateTime.Now;
-      }
-      FwkInfo("DoExecuteExceptionHandling() complete.");
-    }
-    public void DoParitionedRegionFunctionExecution()
-    {
-      FwkInfo("In DoParitionedRegionFunctionExecution()");
-      Apache.Geode.Client.Execution<object> exc = null;
-      IRegion<TKey, TVal> region = GetRegion("partitionedRegion");
-      try
-      {
-        exc = Client.FunctionService<object>.OnRegion<TKey, TVal>(region);
-         MyResultCollector<object> myRC = new MyResultCollector<object>();
-         Random rnd = new Random();
-         if(rnd.Next(100) % 2 == 0)
-         {
-           //Execution on partitionedRegion with no filter
-           exc = exc.WithCollector(myRC);
-         }
-         else
-         {
-           //Execution on partitionedRegion with filter
-          // ICacheableKey<TKey>[]keys = region.GetKeys();
-           ICollection<TKey> keys = region.GetLocalView().Keys;
-                      
-           //ISerializable[] filterObj = new ISerializable[keys.Count];
-           Object[] filterObj = new Object[keys.Count];
-           for (int i = 0; i < keys.Count; i++)
-           {
-             //filterObj[i] = (ISerializable)keys;
-             filterObj[i] = keys;
-           }
-           exc = exc.WithFilter(filterObj).WithCollector(myRC);
-         }
-         // execute function
-         Client.IResultCollector<object> rc = exc.Execute("ExceptionHandlingFunction", TimeSpan.FromSeconds(30));
-
-      }
-      catch (Apache.Geode.Client.FunctionExecutionException)
-      {
-        //expected exception
-      }
-      catch (Apache.Geode.Client.TimeoutException)
-      {
-        //expected exception
-      }
-      FwkInfo("DoParitionedRegionFunctionExecution() complete.");
-    }
-    public void DoReplicatedRegionFunctionExecution()
-    {
-      FwkInfo("In DoReplicatedRegionFunctionExecution()");
-      Apache.Geode.Client.Execution<object> exc = null;
-      IRegion<TKey, TVal> region = GetRegion("replicatedRegion");
-      try
-      {
-        exc = Client.FunctionService<object>.OnRegion<TKey, TVal>(region);
-        MyResultCollector<object> myRC = new MyResultCollector<object>();
-        exc = exc.WithCollector(myRC);
-        // execute function
-        Client.IResultCollector<object> rc = exc.Execute("ExceptionHandlingFunction", TimeSpan.FromSeconds(30));
-      }
-      catch (Apache.Geode.Client.FunctionExecutionException)
-      {
-        //expected exception
-      }
-      catch (Apache.Geode.Client.TimeoutException)
-      {
-        //expected exception
-      }
-      FwkInfo("DoReplicatedRegionFunctionExecution() complete.");
-    }
-    public void DoFireAndForgetFunctionExecution()
-    {
-      FwkInfo("In DoFireAndForgetFunctionExecution()");
-      string name = null;
-      Random rnd = new Random();
-      if(rnd.Next(100) % 2 == 0){
-        //Execution Fire and forget on partitioned region
-        name = "partitionedRegion";
-      }
-      else
-      {
-        //Execution Fire and forget on replicated region
-        name = "replicatedRegion";
-      }
-      IRegion<TKey, TVal> region = GetRegion(name);
-      try
-      {
-        MyResultCollector<object> myRC = new MyResultCollector<object>();
-        Apache.Geode.Client.Execution<object> exc = Client.FunctionService<object>.OnRegion<TKey, TVal>(region).WithCollector(myRC);
-        // execute function
-        Client.IResultCollector<object> rc = exc.Execute("FireNForget", TimeSpan.FromSeconds(30));
-      }
-      catch (Apache.Geode.Client.FunctionExecutionException)
-      {
-        //expected exception
-      }
-      catch (Apache.Geode.Client.TimeoutException)
-      {
-        //expected exception
-      }
-      FwkInfo("DoFireAndForgetFunctionExecution() complete.");
-    }
-    public void DoOnServersFunctionExcecution()
-    {
-      FwkInfo("In DoOnServersFunctionExcecution()");
-      ResetKey("poolName");
-      string poolname = GetStringValue("poolName");
-      Apache.Geode.Client.Execution<object> exc = null;
-      try
-      {
-        Pool/*<TKey, TVal>*/ pptr = CacheHelper<TKey, TVal>.DCache.GetPoolManager().Find(poolname);
-        MyResultCollector<object> myRC = new MyResultCollector<object>();
-        exc = Client.FunctionService<object>.OnServers(pptr).WithCollector(myRC);
-        // execute function
-        Client.IResultCollector<object> rc = exc.Execute("ExceptionHandlingFunction", TimeSpan.FromSeconds(30));
-      }
-      catch (Apache.Geode.Client.FunctionExecutionException)
-      {
-        //expected exception
-      }
-      catch (Apache.Geode.Client.TimeoutException)
-      {
-        //expected exception
-      }
-      FwkInfo("DoOnServersFunctionExcecution() complete.");
-    }
-
-    public void DoExecuteFunctionsHA()
-    {
-      ResetKey("getResult");
-      bool getresult = GetBoolValue("getResult");
-      ResetKey("distinctKeys");
-      int numKeys = GetUIntValue("distinctKeys");
-      IRegion<TKey, TVal> region = GetRegion();
-      ICollection<object> executeFunctionResult = null;
-      string funcName = "GetFunctionExeHA";
-      Apache.Geode.Client.Execution<object> exc = Client.FunctionService<object>.OnRegion<TKey, TVal>(region);
-      MyResultCollectorHA<object> myRC = new MyResultCollectorHA<object>();
-      exc = exc.WithCollector(myRC);
-      Client.IResultCollector<object>  rc = exc.Execute(funcName, TimeSpan.FromSeconds(120));
-      executeFunctionResult = myRC.GetResult();
-      if (executeFunctionResult != null)
-      {
-        IEnumerator<object> enmtor = executeFunctionResult.GetEnumerator();
-        enmtor.MoveNext();
-        //Boolean lastResult = (Boolean)enmtor.Current; //exefuncResult[0];
-        //Boolean lastResult = (Boolean)executeFunctionResult[0];
-       // if (lastResult!= true) 
-       //   FwkException("FunctionExecution::DoExecuteFunctionHA failed, last result is not true");
-        ICollection<object> resultListColl = myRC.GetResult(TimeSpan.FromSeconds(60));
-        string[] resultList = new string[resultListColl.Count];
-        resultList.CopyTo(resultList, 0);
-        //FwkInfo("FunctionExecution::DoExecuteFunctionHA GetClearResultCount {0} GetGetResultCount {1} GetAddResultCount {2}", myRC.GetClearResultCount(), myRC.GetGetResultCount(), myRC.GetAddResultCount());
-        if (resultList != null)
-        {
-          if (numKeys == resultList.Length)
-          {
-            for (int i = 1; i < numKeys; i++)
-            {
-              int count = 0;
-              string key = "key-" + i;
-              
-              for (int j = 0; j < resultList.Length; j++)
-              {
-                if ((key.Equals(resultList[j])))
-                {
-                  count++;
-                  if (count > 1)
-                  {
-                    FwkException("FunctionExecution::DoExecuteFunctionHA: duplicate entry found for key {0} ", key);
-                  }
-                } 
-              }
-              
-              if(count == 0) {
-                  FwkException("FunctionExecution::DoExecuteFunctionHA failed: key is missing in result list {0}", key);
-                }
-              }
-            }
-          }
-          else
-          {
-            FwkException("FunctionExecution::DoExecuteFunctionHA failed: result size {0} doesn't match with number of keys {1}", resultList.Length, numKeys);
-          }
-        }
-        else {
-          FwkException("FunctionExecution::DoExecuteFunctionHA executeFunctionResult is null");
-        }
-        
-      }
-      public void DoGetServerKeys()
-      {
-          try
-          {
-              FwkInfo("FunctionExecution:DoGetServerKeys");
-              IRegion<TKey, TVal> region = GetRegion();
-              TKey[] keys = (TKey[])(object)region.Keys;
-              bool pdxobject = GetBoolValue("isPdxObject");
-              ArrayList args = new ArrayList();
-              args.Add("get");
-              if (pdxobject)
-                  args.Add(pdxobject);
-              //args.Add("pdxobject");
-              for (int i = 0; i < keys.Length; i++)
-                  args.Add(keys[i]);
-              string funcName = GetStringValue("funcName");
-              Apache.Geode.Client.Execution<object> exc =
-                  Client.FunctionService<object>.OnRegion<TKey, TVal>(region);
-              //FwkInfo("Going to do get execute");
-              ICollection<object> executeFunctionResult = null;
-              ResetKey("replicated");
-              bool isReplicate = GetBoolValue("replicated");
-              if (!isReplicate)
-              {
-                  executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<TKey>(keys).Execute(funcName).GetResult();
-              }
-              else
-              {
-                  executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(funcName).GetResult();
-              }
-              if (executeFunctionResult != null)
-              {
-                  foreach (object item in executeFunctionResult)
-                  {
-                      if ((bool)item != true)
-                          FwkException("FunctionExecution:DoGetServerKeys:: failed, last result is not true");
-                  }
-
-              }
-
-          }
-          catch (CacheServerException ex)
-          {
-              FwkException("DoGetServerKeys() Caught CacheServerException: {0}", ex);
-          }
-          catch (Exception ex)
-          {
-              FwkException("DoGetServerKeys() Caught Exception: {0}", ex);
-          }
-       
-      }
-      public void DoUpdateServerKeys()
-      {
-          try
-          {
-              FwkInfo("FunctionExecution:DoGetServerKeys");
-              IRegion<TKey, TVal> region = GetRegion();
-              TKey[] keys = (TKey[])(object)region.Keys;
-              bool pdxobject = GetBoolValue("isPdxObject");
-              ArrayList args = new ArrayList();
-              args.Add("update");
-              if (pdxobject)
-                  args.Add(pdxobject);
-              //args.Add("pdxobject");
-              for (int i = 0; i < keys.Length; i++)
-                  args.Add(keys[i]);
-              string funcName = GetStringValue("funcName");
-              Apache.Geode.Client.Execution<object> exc =
-                  Client.FunctionService<object>.OnRegion<TKey, TVal>(region);
-              //FwkInfo("Going to do get execute");
-              ICollection<object> executeFunctionResult = null;
-              ResetKey("replicated");
-              bool isReplicate = GetBoolValue("replicated");
-              if (!isReplicate)
-              {
-                  executeFunctionResult = exc.WithArgs<ArrayList>(args).WithFilter<TKey>(keys).Execute(funcName).GetResult();
-              }
-              else
-              {
-                  executeFunctionResult = exc.WithArgs<ArrayList>(args).Execute(funcName).GetResult();
-              }
-              if (executeFunctionResult != null)
-              {
-                  foreach (object item in executeFunctionResult)
-                  {
-                      if ((bool)item != true)
-                          FwkException("FunctionExecution:DoGetServerKeys:: failed, last result is not true");
-                  }
-
-              }
-
-          }
-          catch (CacheServerException ex)
-          {
-              FwkException("DoGetServerKeys() Caught CacheServerException: {0}", ex);
-          }
-          catch (Exception ex)
-          {
-              FwkException("DoGetServerKeys() Caught Exception: {0}", ex);
-          }
-
-      }
-      public void doOps()
-      {
-          FwkInfo("FunctionExcution:doOps called.");
-
-          int opsSec = GetUIntValue("opsSecond");
-          opsSec = (opsSec < 1) ? 0 : opsSec;
-
-          int secondsToRun = GetTimeValue("workTime");
-          secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-          int valSize = GetUIntValue("valueSizes");
-          valSize = ((valSize < 0) ? 32 : valSize);
-          ResetKey("entryCount");
-          int entryCount = GetUIntValue("entryCount");
-          ResetKey("NumNewKeys");
-          int numNewKeys = GetUIntValue("NumNewKeys");
-
-          //TestClient * clnt = TestClient::getTestClient();
-          IRegion<TKey, TVal> regionPtr = GetRegion();
-          if (regionPtr == null)
-          {
-              FwkSevere("FunctionExcution:doOps(): No region to perform operations on.");
-              //now = end; // Do not do the loop
-          }
-          ResetKey("useTransactions");
-          bool m_istransaction = GetBoolValue("useTransactions");
-          try
-          {
-              DoFETask<TKey, TVal> dooperation = new DoFETask<TKey, TVal>(regionPtr, m_istransaction);
-              ResetKey("numThreads");
-              int numThreads = GetUIntValue("numThreads");
-              RunTask(dooperation, numThreads, entryCount + numNewKeys + NUM_EXTRA_KEYS, -1, -1, null);
-          }
-          catch (ClientTimeoutException)
-          {
-              FwkException("In FunctionExcution:doOps()  Timed run timed out.");
-          }
-          catch (FwkException e)
-          {
-              FwkException("Caught Exception exception during FunctionExcution:doOps: " + e);
-          }
-          catch (Exception e)
-          {
-              FwkException("Caught unexpected exception during FunctionExcution:doOps: " + e);
-          }
-         
-          
-
-
-          FwkInfo("Done in FunctionExcution:doOps");
-          Thread.Sleep(10000);
-      }
-    }
-  }
diff --git a/tests/cli/NewFwkLib/FunctionExecution/MyResultCollector.cs b/tests/cli/NewFwkLib/FunctionExecution/MyResultCollector.cs
deleted file mode 100644
index f886f41..0000000
--- a/tests/cli/NewFwkLib/FunctionExecution/MyResultCollector.cs
+++ /dev/null
@@ -1,175 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-  public class MyResultCollector<TResult> : Client.IResultCollector<TResult>
-  {
-    #region Private members
-    private Boolean m_resultReady = false;
-    //private CacheableVector m_results = null;
-    ICollection<TResult> m_results = null;
-    private int m_addResultCount = 0;
-    private int m_getResultCount = 0;
-    private int m_endResultCount = 0;
-    #endregion
-    public int GetAddResultCount()
-    {
-      return m_addResultCount;
-    }
-    public int GetGetResultCount()
-    {
-      return m_getResultCount;
-    }
-    public int GetEndResultCount()
-    {
-      return m_endResultCount;
-    }
-    public MyResultCollector()
-    {
-      m_results = new List<TResult>();
-    }
-    public void AddResult(TResult result)
-    {
-      m_addResultCount++;
-      m_results.Add(result);
-    }
-    public ICollection<TResult> GetResult()
-    {
-      return GetResult(TimeSpan.FromSeconds(50));
-    }
-    public ICollection<TResult> GetResult(TimeSpan timeout)
-    {
-      m_getResultCount++;
-
-      lock(this)
-      {
-        if (!m_resultReady)
-        {
-          if (timeout > TimeSpan.Zero) {
-            if (!Monitor.Wait(this, timeout)) {
-              throw new FunctionExecutionException("Timeout waiting for result.");
-            }
-          } else {
-            throw new FunctionExecutionException("Results not ready.");
-          }
-        }
-      }
-
-      return m_results;
-    }
-
-    public void EndResults()
-    {
-      m_endResultCount++;
-
-      lock (this) {
-        m_resultReady = true;
-        Monitor.Pulse(this);
-      }
-    }
-
-    public void ClearResults(/*bool unused*/)
-    {
-      m_results.Clear();
-      m_resultReady = false;
-    }
-
-  }
-  public class MyResultCollectorHA<TResult> : Client.IResultCollector<TResult>
-  {
-    #region Private members
-    private bool m_resultReady = false;
-    //private CacheableVector m_results = null;
-    ICollection<TResult> m_results = null;
-    private int m_addResultCount = 0;
-    private int m_getResultCount = 0;
-    private int m_endResultCount = 0;
-    private int m_clearResultCount = 0;
-    #endregion
-    public int GetAddResultCount()
-    {
-      return m_addResultCount;
-    }
-    public int GetGetResultCount()
-    {
-      return m_getResultCount;
-    }
-    public int GetEndResultCount()
-    {
-      return m_endResultCount;
-    }
-    public int GetClearResultCount()
-    {
-      return m_clearResultCount;
-    }
-    public MyResultCollectorHA()
-    {
-      m_results = new List<TResult>();
-    }
-    public void AddResult(TResult result)
-    {
-      //m_addResultCount++;
-      ////CacheableString rs = result as CacheableString;
-      //string rs = result.ToString();
-      m_results.Add(result);
-    }
-    public ICollection<TResult> GetResult()
-    {
-      return GetResult(TimeSpan.FromSeconds(50));
-    }
-    public ICollection<TResult> GetResult(TimeSpan timeout)
-    {
-      m_getResultCount++;
-
-      lock (this) {
-        if (!m_resultReady) {
-          if (timeout > TimeSpan.Zero) {
-            if (!Monitor.Wait(this, timeout)) {
-              throw new FunctionExecutionException("Timeout waiting for result.");
-            }
-          } else {
-            throw new FunctionExecutionException("Results not ready.");
-          }
-        }
-      }
-
-      return m_results;
-    }
-    public void ClearResults(/*bool unused*/)
-    {
-      m_clearResultCount++;
-      m_results.Clear();
-      m_resultReady = false;
-    }
-    public void EndResults()
-    {
-      m_endResultCount++;
-      lock (this) {
-        m_resultReady = true;
-        Monitor.Pulse(this);
-      }
-    }
-
-  }
-}
diff --git a/tests/cli/NewFwkLib/FwkTask.cs b/tests/cli/NewFwkLib/FwkTask.cs
deleted file mode 100644
index a48fc77..0000000
--- a/tests/cli/NewFwkLib/FwkTask.cs
+++ /dev/null
@@ -1,532 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Reflection;
-using System.Text;
-using System.Xml;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-
-  public class FwkTask
-  {
-    #region Private members
-
-    private Delegate m_delegate;
-    private Delegate m_pushTaskNameDelegate;
-    private Delegate m_endDelegate;
-    private List<string> m_clients;
-    private TimeBomb m_timeBomb;
-    private string m_class;
-    private int m_timeoutMillis;
-    private int m_timesToRun;
-    private int m_threadCount;
-    private bool m_parallel;
-    private bool m_continueOnError;
-    private ClientGroup m_clientGroup;
-    private List<string> m_localDataNames;
-    private UnitFnMethod<FwkTask, ClientBase> m_taskStartedHandler;
-    private UnitFnMethod<FwkTask, ClientBase, Exception> m_taskDoneHandler;
-    private bool m_taskStatus;
-
-    #endregion
-
-    #region Private constants and static members
-
-    private const string PushTaskNameMethod = "PushTaskName";
-    private const string EndTaskMethod = "EndTask";
-    private const int DefaultTimeoutMillis = 600000;
-    private static string[] ThreadCountKeys = { "threadCount", "numThreads" };
-    private static Dictionary<string, int> m_GlobalTaskNames =
-      new Dictionary<string, int>();
-    private static Dictionary<string, Assembly> m_AssemblyMap =
-      new Dictionary<string, Assembly>();
-    private const string ClientCountKey = "clientCount";
-
-    private const string NameAttrib = "name";
-    private const string MethodAttrib = "action";
-    private const string ClassAttrib = "class";
-    private const string ContainerAttrib = "container";
-    private const string WaitTimeAttrib = "waitTime";
-    private const string TimesToRunAttrib = "timesToRun";
-    private const string ThreadCountAttrib = "threadCount";
-    private const string ParallelAttrib = "parallel";
-    private const string ContinueAttrib = "continueOnError";
-    private const string ArgTypes = "argTypes";
-
-    #endregion
-
-    #region Public accessors
-
-    public static Dictionary<string, int> GlobalTaskNames
-    {
-      get
-      {
-        return m_GlobalTaskNames;
-      }
-    }
-
-    public List<string> ClientNames
-    {
-      get
-      {
-        return m_clients;
-      }
-    }
-
-    public string Name
-    {
-      get
-      {
-        return (m_timeBomb == null ? null : m_timeBomb.TaskName);
-      }
-    }
-
-    public string Class
-    {
-      get
-      {
-        return m_class;
-      }
-    }
-
-    public int Timeout
-    {
-      get
-      {
-        return m_timeoutMillis;
-      }
-    }
-
-    public int TimesToRun
-    {
-      get
-      {
-        return m_timesToRun;
-      }
-    }
-
-    public int ThreadCount
-    {
-      get
-      {
-        return m_threadCount;
-      }
-    }
-
-    public bool Parallel
-    {
-      get
-      {
-        return m_parallel;
-      }
-    }
-
-    public bool ContinueOnError
-    {
-      get
-      {
-        return m_continueOnError;
-      }
-    }
-
-    #endregion
-
-    #region Private methods
-
-    private void HandleTaskStarted(ClientBase client)
-    {
-      if (m_taskStartedHandler != null)
-      {
-        m_taskStartedHandler(this, client);
-      }
-    }
-
-    private void HandleTaskDone(ClientBase client, Exception ex)
-    {
-      if (m_taskDoneHandler != null)
-      {
-        m_taskStatus = (ex == null);
-        m_taskDoneHandler(this, client, ex);
-      }
-    }
-
-    #endregion
-
-    #region Public methods
-
-    public FwkTask(XmlNode node, string testName,
-      UnitFnMethod<FwkTask, ClientBase> taskStartedHandler,
-      UnitFnMethod<FwkTask, ClientBase, Exception> taskDoneHandler)
-    {
-      if (node == null)
-      {
-        throw new IllegalArgException("Null node for FwkTask constructor.");
-      }
-
-      #region Read the attributes
-
-      string taskName = string.Empty;
-      string containerStr = null;
-      string methodName = null;
-      string typeAttrib = null;
-      m_timesToRun = 1;
-      m_threadCount = 1;
-      m_parallel = false;
-      m_timeoutMillis = DefaultTimeoutMillis;
-      m_continueOnError = false;
-      m_class = null;
-
-      XmlAttributeCollection xmlAttribs = node.Attributes;
-      if (xmlAttribs != null)
-      {
-        foreach (XmlAttribute xmlAttrib in xmlAttribs)
-        {
-          switch (xmlAttrib.Name)
-          {
-            case NameAttrib:
-              taskName = xmlAttrib.Value;
-              break;
-            case ArgTypes:
-              typeAttrib = xmlAttrib.Value;
-              break;
-            case ContainerAttrib:
-              containerStr = xmlAttrib.Value;
-              break;
-            case MethodAttrib:
-              methodName = xmlAttrib.Value;
-              break;
-            case TimesToRunAttrib:
-              m_timesToRun = XmlNodeReaderWriter.String2Int(xmlAttrib.Value, 1);
-              break;
-            case ThreadCountAttrib:
-              m_threadCount = XmlNodeReaderWriter.String2Int(xmlAttrib.Value, 1);
-              break;
-            case ParallelAttrib:
-              m_parallel = XmlNodeReaderWriter.String2Bool(xmlAttrib.Value, false);
-              break;
-            case WaitTimeAttrib:
-              m_timeoutMillis = XmlNodeReaderWriter.String2Seconds(xmlAttrib.Value,
-                DefaultTimeoutMillis) * 1000;
-              break;
-            case ContinueAttrib:
-              m_continueOnError = XmlNodeReaderWriter.String2Bool(xmlAttrib.Value, false);
-              break;
-            case ClassAttrib:
-              m_class = xmlAttrib.Value;
-              break;
-            default:
-              throw new IllegalArgException("Unknown attribute '" +
-                xmlAttrib.Name + "' found in '" + node.Name +
-                "' node.");
-          }
-        }
-      }
-      int taskNum = 1;
-      if (m_GlobalTaskNames.ContainsKey(taskName))
-      {
-        taskNum = m_GlobalTaskNames[taskName] + 1;
-      }
-      m_GlobalTaskNames[taskName] = taskNum;
-      taskName += '_' + taskNum.ToString();
-
-      #endregion
-
-      m_timeBomb = new TimeBomb();
-      m_timeBomb.TaskName = testName + '.' + taskName;
-
-      #region Create a delegate by loading the assembly
-
-      Assembly loadAssmb = null;
-      string typeName = null;
-      if (containerStr != null && methodName != null)
-      {
-        object inst = null;
-        int dotIndx;
-        if ((dotIndx = containerStr.IndexOf('.')) < 0)
-        {
-          Type myType = this.GetType();
-          loadAssmb = myType.Assembly;
-          typeName = myType.Namespace + '.' + containerStr;
-          Util.Log(Util.LogLevel.Info, "Assembly {0} loaded and typename is {1}", loadAssmb, typeName);
-        }
-        else
-        {
-          string assmbName = containerStr.Substring(0, dotIndx);
-          if (!m_AssemblyMap.TryGetValue(assmbName, out loadAssmb))
-          {
-            try
-            {
-              loadAssmb = Assembly.Load(assmbName);
-              Util.Log(Util.LogLevel.Info, "Assembly {0} loaded ", assmbName);
-            }
-            catch (Exception e)
-            {
-              throw new IllegalArgException("Cannot load assembly '" +
-                assmbName + "' for task: " + m_timeBomb.TaskName +
-                " exception: " + e);
-            }
-            m_AssemblyMap.Add(assmbName, loadAssmb);
-          }
-          typeName = containerStr.Substring(dotIndx + 1);
-        }
-        //string typeAttrib;
-        if (loadAssmb != null)
-        {
-            if (typeAttrib == null)
-            {
-              inst = loadAssmb.CreateInstance(typeName, true);
-            }
-            else
-            {
-              //typeAttrib = "Apache.Geode.Client.Tests.ArrayOfByte,Apache.Geode.Client.Tests.ArrayOfByte";
-              //typeAttrib = "System.int,System.Int32";
-              string[] typeNames = typeAttrib.Split(',');
-              string mangledName = typeName + "`" + typeNames.Length.ToString();
-
-              //Type type = loadAssmb.GetType(mangledName, true, true);
-              Type[] types = new Type[typeNames.Length];
-             for (int index = 0; index < typeNames.Length; ++index)
-              {
-                string typName = typeNames[index].Trim();
-                if (typName == "int" || typName == "Int32" || typName == "string" ||
-                  typName == "String" || typName == "byte[]" || typName == "Byte[]"
-                  || typName == "string[]" || typName == "String[]" || typName == "Object" 
-                  || typName == "object")
-                {
-                  if (typName.Equals("int"))
-                    typName = "Int32";
-                  else if (typName.Equals("string"))
-                    typName = "String";
-                  else if (typName.Equals("string[]"))
-                    typName = "String[]";
-                  else if (typName.Equals("byte[]"))
-                    typName = "Byte[]";
-                  else if (typName.Equals("object"))
-                    typName = "Object";
-                  typName = "System." + typName;
-                  //Util.Log("rjk: FwkTask: typeAttrib 33 argname {0}", typName);
-                  types[index] = Type.GetType(typName.Trim());
-                  //Util.Log("rjk: FwkTask: typeAttrib 34 argname {0}", typName);
-                }
-                else
-                {
-                  typName = "Apache.Geode.Client.Tests." + typName;
-                  types[index] = loadAssmb.GetType(typName.Trim(), true, true);
-                  //Util.Log("rjk: FwkTask: typeAttrib for userobject 34 argname {0}", typName);
-                }
-              }
-
-              Type type = loadAssmb.GetType(mangledName, true, true).MakeGenericType(types);
-              inst = type.GetConstructor(System.Type.EmptyTypes).Invoke(null);
-              
-            }
-          
-        }
-        if (inst != null)
-        {
-          try
-          {
-            MethodInfo mInfo = inst.GetType().GetMethod(methodName,
-              BindingFlags.IgnoreCase | BindingFlags.Public |
-              BindingFlags.Static | BindingFlags.FlattenHierarchy |
-              BindingFlags.Instance);
-            m_delegate = Delegate.CreateDelegate(typeof(UnitFnMethod), inst,
-              mInfo, true);
-          }
-          catch (Exception ex)
-          {
-            throw new IllegalArgException(
-              "Exception while creating delegate [" + methodName + "]: " + ex);
-          }
-          m_pushTaskNameDelegate = Delegate.CreateDelegate(
-            typeof(UnitFnMethod<string>), inst, PushTaskNameMethod, true);
-          m_endDelegate = Delegate.CreateDelegate(
-            typeof(UnitFnMethod), inst, EndTaskMethod, true);
-        }
-      }
-      if (m_delegate == null)
-      {
-        throw new IllegalArgException("Cannot create delegate '" +
-          methodName + "' for task: " + m_timeBomb.TaskName);
-      }
-
-      #endregion
-
-      #region Add the clients
-
-      m_clients = new List<string>();
-      m_clientGroup = new ClientGroup(false);
-      m_clients = FwkClient.ReadClientNames(node, false);
-      List<ClientBase> clients = FwkClient.GetClients(m_clients);
-      m_clientGroup.Add(clients);
-      m_timeBomb.AddClients(new ClientBase[] { m_clientGroup });
-      m_taskStartedHandler = taskStartedHandler;
-      m_taskDoneHandler = taskDoneHandler;
-      int clientCount = m_clients.Count;
-
-      #endregion
-
-      #region Add any data
-
-      m_localDataNames = new List<string>();
-      Dictionary<string, FwkData> data = FwkData.ReadDataNodes(node);
-      // Task specific data is written as <taskname>.<key> to avoid
-      // overwriting the global data, since that needs to be preserved
-      // across tasks.
-      if (m_threadCount > 1)
-      {
-        // We shall treat 'threadCount' and 'numThreads' as equivalent,
-        // i.e. if 'threadCount' is defined for a task then 'numThreads'
-        // shall also be written as data.
-        foreach (string threadKey in ThreadCountKeys)
-        {
-          m_localDataNames.Add(threadKey);
-          Util.BBSet(Name, threadKey,
-            new FwkData(m_threadCount.ToString(), null, DataKind.String));
-        }
-      }
-      if (clientCount > 0)
-      {
-        // Overwrite the clientCount (if any) with the actual value.
-        Util.BBSet(Name, ClientCountKey,
-        new FwkData(clientCount.ToString(), null, DataKind.String));
-      }
-      foreach (KeyValuePair<string, FwkData> pair in data)
-      {
-        m_localDataNames.Add(pair.Key);
-        Util.BBSet(Name, pair.Key, pair.Value);
-      }
-
-      #endregion
-    }
-
-    public void AddClients(params ClientBase[] clients)
-    {
-      m_clientGroup.Add(clients);
-    }
-
-    public void SetClients(params ClientBase[] clients)
-    {
-      m_clientGroup.Clients.Clear();
-      m_clientGroup.Add(clients);
-    }
-
-    public bool Execute()
-    {
-      m_taskStatus = true;
-      m_timeBomb.Start(m_timeoutMillis);
-      try
-      {
-        if (m_pushTaskNameDelegate != null)
-        {
-          m_clientGroup.CallFn(m_pushTaskNameDelegate,
-              new object[] { m_timeBomb.TaskName });
-        }
-        if (m_taskStartedHandler != null || m_taskDoneHandler != null)
-        {
-          m_clientGroup.AddTaskHandlers(HandleTaskStarted, HandleTaskDone);
-        }
-        FwkReadData read = new FwkReadData();
-        read.PushTaskName(Name);
-        string appDomain = read.GetStringValue("appdomain");
-        if (appDomain != null && appDomain.Length > 0) {
-          m_clientGroup.CallFn(m_delegate, new object[] { Util.AppDomainPrefix
-          + appDomain });
-        }
-        else {
-          m_clientGroup.CallFn(m_delegate, null);
-        }
-        if (m_taskStartedHandler != null || m_taskDoneHandler != null)
-        {
-          m_clientGroup.RemoveTaskHandlers(HandleTaskStarted, HandleTaskDone);
-        }
-      }
-      finally
-      {
-        m_timeBomb.Diffuse();
-      }
-      return m_taskStatus;
-    }
-
-    public void ClearData()
-    {
-      foreach (string dataName in m_localDataNames)
-      {
-        Util.BBRemove(Name, dataName);
-      }
-    }
-
-    public void EndTask()
-    {
-      if (m_endDelegate != null)
-      {
-        m_clientGroup.CallFn(m_endDelegate, null);
-      }
-      m_clientGroup.RemoveObject(m_delegate.Target);
-    }
-
-    public void SetLogFile(string logPath)
-    {
-      m_clientGroup.SetNameLogFile(logPath);
-    }
-
-    public void SetLogLevel(Util.LogLevel logLevel)
-    {
-      m_clientGroup.SetLogLevel(logLevel);
-    }
-
-    public string Dump()
-    {
-      StringBuilder dumpStr = new StringBuilder();
-
-      dumpStr.Append(Environment.NewLine + "The task name is: " +
-        m_timeBomb.TaskName);
-      dumpStr.Append(string.Format("{0}The function to be executed: " +
-        "'{1}' in class '{2}'", Environment.NewLine, m_delegate.Method.Name,
-        m_delegate.Method.ReflectedType.FullName));
-      dumpStr.Append(Environment.NewLine + "The class of the task: " +
-        m_class);
-      dumpStr.Append(Environment.NewLine + "The threadCount is: " +
-        m_threadCount);
-      dumpStr.Append(Environment.NewLine + "Parallel attribute is: " +
-        m_parallel);
-      dumpStr.Append(Environment.NewLine + "Times to run is: " +
-        m_timesToRun);
-      dumpStr.Append(Environment.NewLine + "The clients are: ");
-      foreach (string clientName in m_clients)
-      {
-        dumpStr.Append(Environment.NewLine + "\t" + clientName);
-      }
-      dumpStr.Append(Environment.NewLine + "Continue on error is: " +
-        m_continueOnError);
-      dumpStr.Append(Environment.NewLine + "The local data names are: ");
-      foreach (string dataName in m_localDataNames)
-      {
-        dumpStr.Append(Environment.NewLine + '\t' + dataName);
-      }
-      dumpStr.Append(Environment.NewLine + "The timeout is: " +
-        m_timeoutMillis);
-      return dumpStr.ToString();
-    }
-
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/FwkTest.cs b/tests/cli/NewFwkLib/FwkTest.cs
deleted file mode 100644
index 4ab34ce..0000000
--- a/tests/cli/NewFwkLib/FwkTest.cs
+++ /dev/null
@@ -1,1509 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.Serialization;
-using System.Text;
-using System.Xml;
-
-#pragma warning disable 618
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-  using NEWAPI = Apache.Geode.Client.Tests;
-  //using Region = Apache.Geode.Client.IRegion<Object, Object>;
-
-
-  /// <summary>
-  /// Exception thrown when 'Call' is invoked on a client thread/process/...
-  /// that has already exited (either due to some error/exception on the
-  /// client side or due to its 'Dispose' function being called).
-  /// </summary>
-  [Serializable]
-  public class FwkException : Exception
-  {
-    /// <summary>
-    /// Constructor to create an exception object with empty message.
-    /// </summary>
-    public FwkException()
-      : base()
-    {
-    }
-
-    /// <summary>
-    /// Constructor to create an exception object with the given message.
-    /// </summary>
-    /// <param name="message">The exception message.</param>
-    public FwkException(string message)
-      : base(message)
-    {
-    }
-
-    /// <summary>
-    /// Constructor to create an exception object with the given message
-    /// and with the given inner Exception.
-    /// </summary>
-    /// <param name="message">The exception message.</param>
-    /// <param name="innerException">The inner Exception object.</param>
-    public FwkException(string message, Exception innerException)
-      : base(message, innerException)
-    {
-    }
-
-    /// <summary>
-    /// Constructor to allow deserialization of this exception by .Net remoting
-    /// </summary>
-    public FwkException(SerializationInfo info, StreamingContext context)
-      : base(info, context)
-    {
-    }
-  }
-
-  [Serializable]
-  public struct FwkTaskData
-  {
-    #region Private members
-
-    private string m_regionTag;
-    private string m_name;
-    private int m_numClients;
-    private int m_numKeys;
-    private int m_valueSize;
-    private int m_numThreads;
-
-    #endregion
-
-    #region Constructor
-
-    public FwkTaskData(string regionTag, string name, int numClients,
-      int numKeys, int valueSize, int numThreads)
-    {
-      m_regionTag = regionTag;
-      m_name = name;
-      m_numClients = numClients;
-      m_numKeys = numKeys;
-      m_valueSize = valueSize;
-      m_numThreads = numThreads;
-    }
-
-    #endregion
-
-    #region Public methods and accessors
-
-    public string RegionTag
-    {
-      get
-      {
-        return m_regionTag;
-      }
-    }
-
-    public string Name
-    {
-      get
-      {
-        return m_name;
-      }
-    }
-
-    public int NumClients
-    {
-      get
-      {
-        return m_numClients;
-      }
-    }
-
-    public int NumKeys
-    {
-      get
-      {
-        return m_numKeys;
-      }
-    }
-
-    public int ValueSize
-    {
-      get
-      {
-        return m_valueSize;
-      }
-    }
-
-    public int NumThreads
-    {
-      get
-      {
-        return m_numThreads;
-      }
-    }
-
-    public string GetLogString()
-    {
-      return string.Format("{0}-{1}-Clients-{2}-Keys-{3}-VSize-{4}-Threads-{5}",
-        m_regionTag, m_name, m_numClients, m_numKeys, m_valueSize, m_numThreads);
-    }
-
-    public string GetCSVString()
-    {
-      return string.Format("{0},{1},{2},{3},{4},{5}",
-        m_regionTag, m_name, m_numClients, m_numKeys, m_valueSize, m_numThreads);
-    }
-
-    #endregion
-  }
-
-  public abstract class FwkTest<TKey, TVal> : FwkReadData
-  {
-    #region Private members
-
-    private static FwkTest<TKey, TVal> m_currentTest = null;
-    private FwkTaskData m_taskData;
-    private List<string> m_taskRecords;
-    private const NEWAPI.CredentialGenerator.ClassCode DefaultSecurityCode =
-      NEWAPI.CredentialGenerator.ClassCode.LDAP;
-
-    #endregion
-
-    #region Public accessors and constants
-
-    public static FwkTest<TKey, TVal> CurrentTest
-    {
-      get
-      {
-        return m_currentTest;
-      }
-    }
-
-    public const string JavaServerBB = "Cacheservers";
-    public const string EndPointTag = "ENDPOINT:";
-    public const string HeapLruLimitKey = "heapLruLimit";
-    public const string RedundancyLevelKey = "redundancyLevel";
-    public const string ConflateEventsKey = "conflateEvents";
-    public const string SecurityParams = "securityParams";
-    public const string SecurityScheme = "securityScheme";
-    public const string JavaServerEPCountKey = "ServerEPCount";
-    public const string EndPoints = "EndPoints";
-
-    public static Properties<string, string> PER_CLIENT_FOR_MULTIUSER = null;
-    #endregion
-
-    #region Protected members
-
-    protected FwkTaskData TaskData
-    {
-      get
-      {
-        return m_taskData;
-      }
-    }
-
-    #endregion
-
-    #region Public methods
-
-    public FwkTest()
-      : base()
-    {
-      m_currentTest = this;
-      m_taskData = new FwkTaskData();
-      m_taskRecords = new List<string>();
-    }
-
-    public virtual void FwkException(string message)
-    {
-      FwkSevere(message);
-      throw new FwkException(message);
-    }
-
-    public virtual void FwkException(string fmt, params object[] paramList)
-    {
-      FwkException(string.Format(fmt, paramList));
-    }
-
-    public virtual void FwkSevere(string message)
-    {
-      Util.Log(Util.LogLevel.Error, "FWKLIB:: Task[{0}] Severe: {1}",
-        TaskName, message);
-    }
-
-    public virtual void FwkSevere(string fmt, params object[] paramList)
-    {
-      FwkSevere(string.Format(fmt, paramList));
-    }
-
-    public virtual void FwkWarn(string message)
-    {
-      Util.Log(Util.LogLevel.Warning, "FWKLIB:: Task[{0}]: {1}",
-        TaskName, message);
-    }
-
-    public virtual void FwkWarn(string fmt, params object[] paramList)
-    {
-      FwkWarn(string.Format(fmt, paramList));
-    }
-
-    public virtual void FwkInfo(string message)
-    {
-      Util.Log(Util.LogLevel.Info, "FWKLIB:: Task[{0}]: {1}",
-        TaskName, message);
-    }
-
-    public virtual void FwkInfo(string fmt, params object[] paramList)
-    {
-      FwkInfo(string.Format(fmt, paramList));
-    }
-
-    public virtual void FwkAssert(bool condition, string message)
-    {
-      if (!condition)
-      {
-        FwkException(message);
-      }
-    }
-
-    public virtual void FwkAssert(bool condition, string fmt,
-      params object[] paramList)
-    {
-      if (!condition)
-      {
-        FwkException(fmt, paramList);
-      }
-    }
-
-    public static void LogException(string message)
-    {
-      throw new FwkException(message);
-    }
-
-    public static void LogException(string fmt, params object[] paramList)
-    {
-      LogException(string.Format(fmt, paramList));
-    }
-
-    public static void LogSevere(string message)
-    {
-      Util.Log(Util.LogLevel.Error, "FWKLIB:: Severe: {0}", message);
-    }
-
-    public static void LogSevere(string fmt, params object[] paramList)
-    {
-      LogSevere(string.Format(fmt, paramList));
-    }
-
-    public static void LogWarn(string message)
-    {
-      Util.Log(Util.LogLevel.Warning, "FWKLIB:: {0}", message);
-    }
-
-    public static void LogWarn(string fmt, params object[] paramList)
-    {
-      LogWarn(string.Format(fmt, paramList));
-    }
-
-    public static void LogInfo(string message)
-    {
-      Util.Log(Util.LogLevel.Info, "FWKLIB:: {0}", message);
-    }
-
-    public static void LogInfo(string fmt, params object[] paramList)
-    {
-      LogInfo(string.Format(fmt, paramList));
-    }
-
-    public static void LogAssert(bool condition, string message)
-    {
-      if (!condition)
-      {
-        LogException(message);
-      }
-    }
-
-    public static void LogAssert(bool condition, string fmt,
-      params object[] paramList)
-    {
-      if (!condition)
-      {
-        LogException(fmt, paramList);
-      }
-    }
-
-    public virtual IRegion<TKey, TVal> GetRootRegion()
-    {
-      string rootRegionData = GetStringValue("regionSpec");
-      //rootRegionData = rootRegionData + "New";
-      if (rootRegionData == null)
-      {
-        return null;
-      }
-      string rootRegionName = GetRegionName(rootRegionData);
-      try
-      {
-        return CacheHelper<TKey, TVal>.GetVerifyRegion(rootRegionName);
-      }
-      catch
-      {
-        return null;
-      }
-    }
-    
-    public CredentialGenerator GetCredentialGenerator()
-    {
-      int schemeNumber;
-      try
-      {
-        schemeNumber = (int)Util.BBGet(string.Empty,
-          FwkReadData.TestRunNumKey);
-      }
-      catch (Exception)
-      {
-        schemeNumber = 1;
-      }
-      int schemeSkip = 1;
-      string securityScheme;
-      string bb = "GFE_BB";
-      string key = "scheme";
-      do
-      {
-        securityScheme = GetStringValue(SecurityScheme);
-        Util.BBSet(bb, key, securityScheme);
-      }
-      while (++schemeSkip <= schemeNumber);
-      NEWAPI.CredentialGenerator.ClassCode secCode;
-      try
-      {
-        secCode = (NEWAPI.CredentialGenerator.ClassCode)Enum.Parse(typeof(
-          NEWAPI.CredentialGenerator.ClassCode), securityScheme, true);
-      }
-      catch (Exception)
-      {
-        FwkWarn("Skipping unknown security scheme {0}. Using default " +
-          "security scheme {1}.", securityScheme, DefaultSecurityCode);
-        secCode = DefaultSecurityCode;
-      }
-      if (secCode == NEWAPI.CredentialGenerator.ClassCode.None)
-      {
-        return null;
-      }
-      NEWAPI.CredentialGenerator gen = NEWAPI.CredentialGenerator.Create(secCode, false);
-      if (gen == null)
-      {
-        FwkWarn("Skipping security scheme {0} with no generator. Using " +
-          "default security scheme.", secCode, DefaultSecurityCode);
-        secCode = DefaultSecurityCode;
-        gen = NEWAPI.CredentialGenerator.Create(secCode, false);
-      }
-
-      return gen;
-    }
-
-    public void GetClientSecurityProperties(ref Properties<string, string> props,
-      string regionName)
-    {
-      string securityParams = GetStringValue(SecurityParams);
-      NEWAPI.CredentialGenerator gen;//= GetCredentialGenerator();
-      if (securityParams == null || securityParams.Length == 0 ||
-        (gen = GetCredentialGenerator()) == null)
-      {
-        FwkInfo("Security is DISABLED.");
-        return;
-      }
-
-      FwkInfo("Security params is: " + securityParams);
-      FwkInfo("Security scheme: " + gen.GetClassCode());
-      string dataDir = Util.GetFwkLogDir(Util.SystemType) + "/data";
-      gen.Init(dataDir, dataDir);
-
-      if (props == null)
-      {
-        props = new Properties<string, string>();
-      }
-
-      Properties<string, string> credentials;
-      Random rnd = new Random();
-      if (securityParams.Equals("valid"))
-      {
-        FwkInfo("Getting valid credentials");
-        credentials = gen.GetValidCredentials(rnd.Next());
-      }
-      else if (securityParams.Equals("invalid"))
-      {
-        FwkInfo("Getting invalid credentials");
-        credentials = gen.GetInvalidCredentials(rnd.Next());
-      }
-      else
-      {
-        FwkInfo("Getting credentials for a list of operations");
-        List<OperationCode> opCodes = new List<OperationCode>();
-        while (securityParams != null && securityParams.Length > 0)
-        {
-          securityParams = securityParams.ToLower().Replace("_", "");
-          OperationCode opCode;
-          if (securityParams == "create" || securityParams == "update")
-          {
-            opCode = OperationCode.Put;
-          }
-          else
-          {
-            opCode = (OperationCode)Enum.Parse(typeof(
-              OperationCode), securityParams, true);
-          }
-          opCodes.Add(opCode);
-          securityParams = GetStringValue(SecurityParams);
-          FwkInfo("Next security params: {0}", securityParams);
-        }
-        // For now only XML based authorization is supported
-        NEWAPI.AuthzCredentialGenerator authzGen = new NEWAPI.XmlAuthzCredentialGenerator();
-        authzGen.Init(gen);
-        List<string> regionNameList = new List<string>();
-        if (regionName == null || regionName.Length == 0)
-        {
-          regionName = GetStringValue("regionPaths");
-        }
-        while (regionName != null && regionName.Length > 0)
-        {
-          regionNameList.Add(regionName);
-          regionName = GetStringValue("regionPaths");
-        }
-        string[] regionNames = null;
-        if (regionNameList.Count > 0)
-        {
-          regionNames = regionNameList.ToArray();
-        }
-        credentials = authzGen.GetAllowedCredentials(opCodes.ToArray(),
-          regionNames, rnd.Next());
-      }
-      PER_CLIENT_FOR_MULTIUSER = credentials;
-      NEWAPI.Utility.GetClientProperties(gen.AuthInit, credentials, ref props);
-      FwkInfo("Security properties entries: {0}", props);
-    }
-    private string[] GetRoundRobinEP()
-    {
-      int contactnum = GetUIntValue("contactNum");
-      string label = "EndPoints";
-      int epCount = (int)Util.BBGet(JavaServerBB, JavaServerEPCountKey);
-      //int epCount = (int)Util.BBGet("GFE_BB", "EP_COUNT");
-      if (contactnum < 0)
-        contactnum = epCount;
-      string[] rbEP = new string[contactnum];
-      string currEPKey = "CURRENTEP_COUNT";
-      int currentEP = (int)Util.BBIncrement("GFERR_BB", currEPKey);
-      for (int i = 0; i < contactnum; i++)
-      {
-        if (currentEP > epCount)
-        {
-          Util.BBSet("GFERR_BB", currEPKey, 0);
-          currentEP = (int)Util.BBIncrement("GFERR_BB", currEPKey);
-        }
-        string key = label + "_" + currentEP.ToString();
-        string ep = (string)Util.BBGet(JavaServerBB, key);
-        rbEP[i] = ep;
-        FwkInfo("GetRoundRobinEP = {0} key = {1} currentEP =  {2}", ep, key, currentEP);
-        //  rbEP[i] = ep;
-      }
-      return rbEP;
-    }
-    private void XMLParseEndPoints(string ep, bool isServer, PoolFactory pf)
-    {
-      string[] eps = ep.Split(',');
-      if (isServer)
-      {
-        bool disableShufflingEP = GetBoolValue("disableShufflingEP"); // smoke perf test
-        if (disableShufflingEP)
-        {
-          string[] rbep = GetRoundRobinEP();
-          for (int cnt = 0; cnt < rbep.Length; cnt++)
-          {
-            FwkInfo("round robin endpoint = {0}", rbep[cnt]);
-            //string[] rep = rbep[cnt].Split(',');
-            //foreach (string endpoint in eps)
-            //{
-              string hostName = rbep[cnt].Split(':')[0];
-              int portNum = int.Parse(rbep[cnt].Split(':')[1]);
-              pf.AddServer(hostName, portNum);
-            //}
-          }
-        }
-        else
-        {
-          foreach (string endpoint in eps)
-          {
-            string hostName = endpoint.Split(':')[0];
-            int portNum = int.Parse(endpoint.Split(':')[1]);
-            pf.AddServer(hostName, portNum);
-          }
-        }
-      }
-      else
-      {
-        foreach (string endpoint in eps)
-        {
-          string hostName = endpoint.Split(':')[0];
-          int portNum = int.Parse(endpoint.Split(':')[1]);
-          pf.AddLocator(hostName, portNum);
-        }
-      }
-    }
-
-     
-      private void CreateCache()
-    {
-      Properties<string,string> dsProps = new Properties<string,string>();
-      ResetKey("PdxReadSerialized");
-      bool pdxReadSerialized = GetBoolValue("PdxReadSerialized");
-      ResetKey("isDurable");
-      bool isDC = GetBoolValue("isDurable");
-      ResetKey("durableTimeout");
-      int durableTimeout = 300;
-      string durableClientId = "";
-      string conflateEvents = GetStringValue(ConflateEventsKey);
-      if (isDC)
-      {
-        durableTimeout = GetUIntValue("durableTimeout");
-        bool isFeeder = GetBoolValue("isFeeder");
-        if (isFeeder)
-        {
-          durableClientId = "Feeder";
-          // VJR: Setting FeederKey because listener cannot read boolean isFeeder
-          // FeederKey is used later on by Verify task to identify feeder's key in BB
-          durableClientId = String.Format("ClientName_{0}_Count", Util.ClientNum);
-       }
-        else
-        {
-          durableClientId = String.Format("ClientName_{0}", Util.ClientNum);
-        }
-        //Util.BBSet("DURABLEBB", durableClientId,0);
-        CacheHelper<TKey, TVal>.InitConfigForPoolDurable(durableClientId, durableTimeout, conflateEvents, false);
-      }
-      else if (pdxReadSerialized)
-      {
-          CacheHelper<TKey, TVal>.InitConfigPdxReadSerialized(dsProps, pdxReadSerialized);
-      }
-      else
-          CacheHelper<TKey, TVal>.InitConfigPool(dsProps);
-    }
-    public void CreateCacheConnect()
-    {
-      CreateCache();
-    }
-    public virtual void CreatePool()
-    {
-      CreateCache();
-      PoolFactory pf =  CacheHelper<TKey, TVal>.DCache.GetPoolFactory();
-      ResetKey("poolSpec");
-      string poolRegionData = GetStringValue("poolSpec");
-      FwkInfo("PoolSpec is :{0}", poolRegionData);
-      string poolName = null;
-      SetPoolAttributes(pf, poolRegionData, ref poolName);
-      
-      if (CacheHelper<TKey, TVal>.DCache.GetPoolManager().Find(poolName) == null)
-      {
-        Pool pool = pf.Create(poolName);
-        FwkInfo("Pool attributes are {0}:", PoolAttributesToString(pool));
-      }
-    }
-    public void SetPoolAttributes(PoolFactory pf, string spec, ref string poolName)
-    {
-      ReadXmlData(null, pf, spec, ref poolName);
-    }
-    private void SetThisPoolAttributes(PoolFactory pf,string key, string value)
-    {
-      switch (key)
-      {
-        case "free-connection-timeout":
-          int fct = int.Parse(value);
-           pf.SetFreeConnectionTimeout(TimeSpan.FromSeconds(fct));
-           break;
-        case "idle-timeout":
-          int it = int.Parse(value);
-            pf.SetIdleTimeout(TimeSpan.FromSeconds(it));
-            break;
-        case "load-conditioning-interval":
-          int lci = int.Parse(value);
-            pf.SetLoadConditioningInterval(TimeSpan.FromSeconds(lci));
-          break;
-        case "max-connections":
-          int mxc = int.Parse(value);
-            pf.SetMaxConnections(mxc);
-            break;
-        case "min-connections":
-          int minc = int.Parse(value);
-           pf.SetMinConnections(minc);
-           break;
-        case "ping-interval":
-          int pi = int.Parse(value);
-            pf.SetPingInterval(TimeSpan.FromSeconds(pi));
-            break;
-        case "read-timeout":
-          int rt = int.Parse(value);
-           pf.SetReadTimeout(TimeSpan.FromSeconds(rt));
-           break;
-        case "retry-attempts":
-          int ra = int.Parse(value);
-            pf.SetRetryAttempts(ra);
-            break;
-        case "server-group":
-           pf.SetServerGroup(value);
-          break;
-        case "socket-buffer-size":
-          int bs = int.Parse(value);
-          pf.SetSocketBufferSize(bs);
-          break;
-        case "subscription-ack-interval":
-           int acki = int.Parse(value);
-            pf.SetSubscriptionAckInterval(TimeSpan.FromSeconds(acki));
-            break;
-        case "subscription-enabled":
-           if (value == "true")
-            {
-              pf.SetSubscriptionEnabled(true);
-            }
-            else
-            {
-              pf.SetSubscriptionEnabled(false);
-            }
-          break;
-        case "thread-local-connections":
-          if (value == "true")
-          {
-              pf.SetThreadLocalConnections(true);
-          }
-          else
-          {
-              pf.SetThreadLocalConnections(false);
-          }
-          break;
-        case "subscription-message-tracking-timeout":
-            int smtt = int.Parse(value);
-            pf.SetSubscriptionMessageTrackingTimeout(TimeSpan.FromSeconds(smtt));
-            break;
-        case "subscription-redundancy":
-            int sr = int.Parse(value);
-            pf.SetSubscriptionRedundancy(sr);
-            break;
-        case "locators":
-          string locatorAddress = (string)Util.BBGet(string.Empty, "LOCATOR_ADDRESS_POOL");
-            XMLParseEndPoints(locatorAddress, false, pf);
-            break;
-        case "servers":
-            string ServerEndPoints = (string)Util.BBGet("Cacheservers", "ENDPOINT:");
-            XMLParseEndPoints(ServerEndPoints, true, pf);
-            break;
-      }
-    }
-    /*
-    public PoolFactory CreatePoolFactoryAndSetAttribute()
-    {
-      PoolFactory pf = PoolManager.CreateFactory();
-      ResetKey("poolSpec");
-      string poolRegionData = GetStringValue("poolSpec");
-      //FwkInfo("PoolSpec is :{0}", poolRegionData);
-      //Properties prop = GetNewPoolAttributes(poolRegionData);
-      staing poolName = null;
-      SetPoolAttributes(pf, poolRegionData,poolName);
-      return pf;
-    }*/
-    private void ReadXmlData(RegionFactory af, PoolFactory pf,string spec, ref string poolname)
-    {
-      const string DriverNodeName = "test-driver";
-      string xmlFile = Util.BBGet(string.Empty, "XMLFILE") as string;
-      XmlNode node = XmlNodeReaderWriter.GetInstance(xmlFile).GetNode(
-           '/' + DriverNodeName);
-      XmlNodeList xmlNodes = node.SelectNodes("data");
-      if (xmlNodes != null)
-      {
-        foreach (XmlNode xmlNode in xmlNodes)
-        {
-          XmlAttribute tmpattr = xmlNode.Attributes["name"];
-          if(tmpattr.Value == spec)
-          {
-          if (xmlNode.FirstChild.Name == "snippet")
-          {
-            string regionName;
-            if (xmlNode.FirstChild.FirstChild.Name == "region")
-            {
-              XmlAttribute nameattr = xmlNode.FirstChild.FirstChild.Attributes["name"];
-              regionName = nameattr.Value;
-              XmlNode attrnode = xmlNode.FirstChild.FirstChild.FirstChild;
-
-              if (attrnode.Name == "region-attributes")
-              {
-                XmlAttributeCollection attrcoll = attrnode.Attributes;
-                if (attrcoll != null)
-                {
-                  foreach (XmlAttribute eachattr in attrcoll)
-                  {
-                    SetThisAttribute(eachattr.Name, eachattr, af, ref poolname);
-                   }
-                }
-                if (attrnode.ChildNodes != null)
-                {
-                  foreach (XmlNode tmpnode in attrnode.ChildNodes)
-                  {
-                    SetThisAttribute(tmpnode.Name, tmpnode, af, ref poolname);
-                  }
-                }
-                else
-                {
-                  throw new IllegalArgException("The xml file passed has an unknown format");
-                }
-              }
-            }
-            else if (xmlNode.FirstChild.FirstChild.Name == "pool")
-            {
-              XmlAttribute nameattr = xmlNode.FirstChild.FirstChild.Attributes["name"];
-              poolname = nameattr.Value;
-              // Now collect the pool atributes
-              Properties<string,string> prop = new Properties<string,string>();
-              XmlAttributeCollection attrcoll = xmlNode.FirstChild.FirstChild.Attributes;
-              if (attrcoll != null)
-              {
-                foreach (XmlAttribute eachattr in attrcoll)
-                {
-                  SetThisPoolAttributes(pf, eachattr.Name, eachattr.Value);
-                }
-              }
-              else
-              {
-                throw new IllegalArgException("The xml file passed has an unknown format");
-              }
-            }
-          }
-        }
-        }
-      }
-    }
-    private static ExpirationAction StrToExpirationAction(string str)
-    {
-      return (ExpirationAction)Enum.Parse(typeof(ExpirationAction),
-        str.Replace("-", string.Empty), true);
-    }
-    public void SetRegionAttributes(RegionFactory af, string spec, ref string poolname)
-    {
-      ReadXmlData(af, null,spec, ref poolname);
-    }
-    public static void SetThisAttribute(string name, XmlNode node, RegionFactory af, ref string poolname)
-    {
-      string value = node.Value;
-      switch (name)
-      {
-        case "caching-enabled":
-          if (value == "true")
-          {
-            af.SetCachingEnabled(true);
-          }
-          else
-          {
-            af.SetCachingEnabled(false);
-          }
-          break;
-
-        case "load-factor":
-          float lf = float.Parse(value);
-          af.SetLoadFactor(lf);
-          break;
-
-        case "concurrency-level":
-          int cl = int.Parse(value);
-          af.SetConcurrencyLevel(cl);
-          break;
-
-        case "lru-entries-limit":
-          uint lel = uint.Parse(value);
-          af.SetLruEntriesLimit(lel);
-          break;
-
-        case "initial-capacity":
-          int ic = int.Parse(value);
-          af.SetInitialCapacity(ic);
-          break;
-
-        case "disk-policy":
-          if (value == "none")
-          {
-            af.SetDiskPolicy(DiskPolicyType.None);
-          }
-          else if (value == "overflows")
-          {
-            af.SetDiskPolicy(DiskPolicyType.Overflows);
-          }
-          else
-          {
-            throw new IllegalArgException("Unknown disk policy");
-          }
-          break;
-      case "concurrency-checks-enabled":
-          bool cce = bool.Parse(value);
-          af.SetConcurrencyChecksEnabled(cce);
-          break;
-      case "pool-name":
-          if (value.Length != 0)
-          {
-            af.SetPoolName(value);
-          }
-          else
-          {
-            af.SetPoolName(value);
-          }
-          poolname = value;
-          break;
-        
-        case "region-time-to-live":
-          XmlNode nlrttl = node.FirstChild;
-          if (nlrttl.Name == "expiration-attributes")
-          {
-            XmlAttributeCollection exAttrColl = nlrttl.Attributes;
-            ExpirationAction action = StrToExpirationAction(exAttrColl["action"].Value);
-            string rttl = exAttrColl["timeout"].Value;
-            af.SetRegionTimeToLive(action, TimeSpan.FromSeconds(uint.Parse(rttl)));
-          }
-          else
-          {
-            throw new IllegalArgException("The xml file passed has an unknowk format");
-          }
-          break;
-
-        case "region-idle-time":
-          XmlNode nlrit = node.FirstChild;
-          if (nlrit.Name == "expiration-attributes")
-          {
-            XmlAttributeCollection exAttrColl = nlrit.Attributes;
-            ExpirationAction action = StrToExpirationAction(exAttrColl["action"].Value);
-            string rit = exAttrColl["timeout"].Value;
-            af.SetRegionIdleTimeout(action, TimeSpan.FromSeconds(uint.Parse(rit)));
-          }
-          else
-          {
-            throw new IllegalArgException("The xml file passed has an unknowk format");
-          }
-          break;
-
-        case "entry-time-to-live":
-          XmlNode nlettl = node.FirstChild;
-          if (nlettl.Name == "expiration-attributes")
-          {
-            XmlAttributeCollection exAttrColl = nlettl.Attributes;
-            ExpirationAction action = StrToExpirationAction(exAttrColl["action"].Value);
-            string ettl = exAttrColl["timeout"].Value;
-            af.SetEntryTimeToLive(action, TimeSpan.FromSeconds(uint.Parse(ettl)));
-          }
-          else
-          {
-            throw new IllegalArgException("The xml file passed has an unknowk format");
-          }
-          break;
-
-        case "entry-idle-time":
-          XmlNode nleit = node.FirstChild;
-          if (nleit.Name == "expiration-attributes")
-          {
-            XmlAttributeCollection exAttrColl = nleit.Attributes;
-            ExpirationAction action = StrToExpirationAction(exAttrColl["action"].Value);
-            string eit = exAttrColl["timeout"].Value;
-            af.SetEntryIdleTimeout(action, TimeSpan.FromSeconds(uint.Parse(eit)));
-          }
-          else
-          {
-            throw new IllegalArgException("The xml file passed has an unknowk format");
-          }
-          break;
-
-        case "cache-loader":
-          XmlAttributeCollection loaderattrs = node.Attributes;
-          string loaderlibrary = null;
-          string loaderfunction = null;
-          foreach (XmlAttribute tmpattr in loaderattrs)
-          {
-            if (tmpattr.Name == "library")
-            {
-              loaderlibrary = tmpattr.Value;
-            }
-            else if (tmpattr.Name == "function")
-            {
-              loaderfunction = tmpattr.Value;
-            }
-            else
-            {
-              throw new IllegalArgException("cahe-loader attributes in improper format");
-            }
-          }
-          if (loaderlibrary != null && loaderfunction != null)
-          {
-            if (loaderfunction.IndexOf('.') < 0)
-            {
-              Type myType = typeof(FwkTest<TKey, TVal>);
-              loaderfunction = myType.Namespace + '.' +
-                loaderlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + loaderfunction;
-              loaderlibrary = myType.Assembly.FullName;
-
-              ICacheLoader<TKey, TVal> loader = null;
-
-              String createCacheLoader = myType.Namespace + '.' +
-                loaderlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createCacheLoader";
-
-              Util.Log(Util.LogLevel.Info, "Instantiated Loader = {0} ", loaderfunction);
-              af.SetCacheLoader(loader);
-            }
-            //af.SetCacheLoader(loaderlibrary, loaderfunction);
-          }
-          break;
-
-        case "cache-listener":
-          XmlAttributeCollection listenerattrs = node.Attributes;
-          string listenerlibrary = null;
-          string listenerfunction = null;
-          foreach (XmlAttribute tmpattr in listenerattrs)
-          {
-            if (tmpattr.Name == "library")
-            {
-              listenerlibrary = tmpattr.Value;
-            }
-            else if (tmpattr.Name == "function")
-            {
-              listenerfunction = tmpattr.Value;
-            }
-            else
-            {
-              throw new IllegalArgException("cahe-listener attributes in improper format");
-            }
-          }
-          if (listenerlibrary != null && listenerfunction != null)
-          {
-            if (listenerfunction.IndexOf('.') < 0)
-            {
-              Type myType = typeof(FwkTest<TKey, TVal>);
-              listenerfunction = myType.Namespace + '.' +
-                listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + listenerfunction;
-              //Util.Log(Util.LogLevel.Info, "rjk1 cache listener in fwktest: myType.Namespace {0} " +
-              //          " listenerlibrary {1} listenerfunction {2}", myType.Namespace, listenerlibrary, listenerfunction);
-              //listenerlibrary = myType.Assembly.FullName;
-              //Util.Log(Util.LogLevel.Info, "rjk cache listener in fwktest inside if condition: listenerlibrary {0} listenerfunction {1}", listenerlibrary, listenerfunction);
-
-              Util.Log(Util.LogLevel.Info, "listenerlibrary is {0} and listenerfunction is {1}", listenerlibrary, listenerfunction);
-              ICacheListener<TKey, TVal> listener = null;
-
-              String perfTestCacheListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createPerfTestCacheListener";
-              String conflationTestCacheListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createConflationTestCacheListener";
-              String latencyListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createLatencyListenerP";
-              String dupChecker = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createDupChecker";
-              String createDurableCacheListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createDurableCacheListener";
-              String createConflationTestCacheListenerDC = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createConflationTestCacheListenerDC";
-              String createDurablePerfListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createDurablePerfListener";              
-              String CreateDurableCacheListenerSP = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createDurableCacheListenerSP";
-              String createLatencyListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createLatencyListener";
-              String createSilenceListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createSilenceListener";
-              String createDeltaValidationCacheListener = myType.Namespace + '.' +
-                  listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createDeltaValidationCacheListener";
-              String createSilenceListenerPdx = myType.Namespace + '.' +
-                                listenerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + "createSilenceListenerPdx";
-
-              if (String.Compare(listenerfunction, perfTestCacheListener, true) == 0) {                
-                listener = new PerfTestCacheListener<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, conflationTestCacheListener, true) == 0) {                
-                listener = new ConflationTestCacheListener<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, latencyListener, true) == 0) {                
-                listener = new LatencyListener<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, dupChecker, true) == 0) {                
-                listener = new DupChecker<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, createDurableCacheListener, true) == 0) {                
-                listener = new DurableListener<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, createConflationTestCacheListenerDC, true) == 0) {                
-                listener = new ConflationTestCacheListenerDC<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, createDurablePerfListener, true) == 0) {                
-                listener = new DurablePerfListener<TKey, TVal>();
-              }              
-              else if (String.Compare(listenerfunction, createSilenceListener, true) == 0)
-              {
-                listener = new SilenceListener<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, createSilenceListenerPdx, true) == 0)
-              {
-                  listener = new PDXSilenceListener<TKey, TVal>();
-              }
-              else if (String.Compare(listenerfunction, createDeltaValidationCacheListener, true) == 0)
-              {
-                listener = new DeltaClientValidationListener<TKey, TVal>();
-              }
-              Util.Log(Util.LogLevel.Info, "Instantiated Listener = {0} ", listenerfunction);
-              af.SetCacheListener(listener);              
-            }                       
-            //af.SetCacheListener(listenerlibrary, listenerfunction);
-          }
-          break;
-
-        case "cache-writer":
-          XmlAttributeCollection writerattrs = node.Attributes;
-          string writerlibrary = null;
-          string writerfunction = null;
-          foreach (XmlAttribute tmpattr in writerattrs)
-          {
-            if (tmpattr.Name == "library")
-            {
-              writerlibrary = tmpattr.Value;
-            }
-            else if (tmpattr.Name == "function")
-            {
-              writerfunction = tmpattr.Value;
-            }
-            else
-            {
-              throw new IllegalArgException("cahe-loader attributes in improper format");
-            }
-          }
-          if (writerlibrary != null && writerfunction != null)
-          {
-            if (writerfunction.IndexOf('.') < 0)
-            {
-              Type myType = typeof(FwkTest<TKey, TVal>);
-              writerfunction = myType.Namespace + '.' +
-                writerlibrary + "<" + typeof(TKey) + "," + typeof(TVal) + ">." + writerfunction;
-              writerlibrary = myType.Assembly.FullName;
-            }
-            af.SetCacheWriter(writerlibrary, writerfunction);
-          }
-          break;
-
-        case "persistence-manager":
-          string pmlibrary = null;
-          string pmfunction = null;
-          Properties<string, string> prop = new Properties<string, string>();
-          XmlAttributeCollection pmattrs = node.Attributes;
-          foreach (XmlAttribute attr in pmattrs)
-          {
-            if (attr.Name == "library")
-            {
-                pmlibrary = attr.Value;
-            }
-            else if (attr.Name == "function")
-            {
-                pmfunction = attr.Value;
-            }
-            else
-            {
-              throw new IllegalArgException("Persistence Manager attributes in wrong format: " + attr.Name);
-            }
-          }
-
-          if (node.FirstChild.Name == "properties")
-          {
-            XmlNodeList pmpropnodes = node.FirstChild.ChildNodes;
-            foreach (XmlNode propnode in pmpropnodes)
-            {
-              if (propnode.Name == "property")
-              {
-                XmlAttributeCollection keyval = propnode.Attributes;
-                XmlAttribute keynode = keyval["name"];
-                XmlAttribute valnode = keyval["value"];
-
-                if (keynode.Value == "PersistenceDirectory" || keynode.Value == "EnvironmentDirectory")
-                {
-                  prop.Insert(keynode.Value, valnode.Value);
-                }
-                else if (keynode.Value == "CacheSizeGb" || keynode.Value == "CacheSizeMb"
-                         || keynode.Value == "PageSize" || keynode.Value == "MaxFileSize")
-                {
-                  prop.Insert(keynode.Value, valnode.Value);
-                }
-              }
-            }
-          }
-          af.SetPersistenceManager(pmlibrary, pmfunction, prop);
-          break;
-      }
-    }
-      private static string ConvertStringArrayToString(string[] array)
-      {
-          //
-          // Concatenate all the elements into a StringBuilder.
-          //
-          StringBuilder builder = new StringBuilder();
-          foreach (string value in array)
-          {
-              builder.Append(value);
-              builder.Append('.');
-          }
-          return builder.ToString();
-      }
-
-      private string PoolAttributesToString(Pool attrs)
-      {
-          StringBuilder attrsSB = new StringBuilder();
-          attrsSB.Append(Environment.NewLine + "poolName: " +
-            attrs.Name);
-          attrsSB.Append(Environment.NewLine + "FreeConnectionTimeout: " +
-            attrs.FreeConnectionTimeout);
-          attrsSB.Append(Environment.NewLine + "LoadConditioningInterval: " +
-           attrs.LoadConditioningInterval);
-          attrsSB.Append(Environment.NewLine + "SocketBufferSize: " +
-            attrs.SocketBufferSize);
-          attrsSB.Append(Environment.NewLine + "ReadTimeout: " +
-            attrs.ReadTimeout);
-          attrsSB.Append(Environment.NewLine + "MinConnections: " +
-            attrs.MinConnections);
-          attrsSB.Append(Environment.NewLine + "MaxConnections: " +
-            attrs.MaxConnections);
-          attrsSB.Append(Environment.NewLine + "StatisticInterval: " +
-            attrs.StatisticInterval);
-          attrsSB.Append(Environment.NewLine + "RetryAttempts: " +
-            attrs.RetryAttempts);
-          attrsSB.Append(Environment.NewLine + "SubscriptionEnabled: " +
-            attrs.SubscriptionEnabled);
-          attrsSB.Append(Environment.NewLine + "SubscriptionRedundancy: " +
-            attrs.SubscriptionRedundancy);
-          attrsSB.Append(Environment.NewLine + "SubscriptionAckInterval: " +
-            attrs.SubscriptionAckInterval);
-          attrsSB.Append(Environment.NewLine + "SubscriptionMessageTrackingTimeout: " +
-            attrs.SubscriptionMessageTrackingTimeout);
-          attrsSB.Append(Environment.NewLine + "ServerGroup: " +
-            attrs.ServerGroup);
-          attrsSB.Append(Environment.NewLine + "IdleTimeout: " +
-            attrs.IdleTimeout);
-          attrsSB.Append(Environment.NewLine + "PingInterval: " +
-            attrs.PingInterval);
-          attrsSB.Append(Environment.NewLine + "ThreadLocalConnections: " +
-            attrs.ThreadLocalConnections);
-          attrsSB.Append(Environment.NewLine + "MultiuserAuthentication: " +
-            attrs.MultiuserAuthentication);
-          attrsSB.Append(Environment.NewLine + "PRSingleHopEnabled: " +
-            attrs.PRSingleHopEnabled);
-          attrsSB.Append(Environment.NewLine + "Locators: " );
-          if (attrs.Locators != null && attrs.Locators.Length > 0)
-          {
-              foreach (string value in attrs.Locators)
-              {
-                  attrsSB.Append(value);
-                  attrsSB.Append(',');
-              }
-          }
-          attrsSB.Append(Environment.NewLine + "Servers: " );
-          if (attrs.Servers != null && attrs.Servers.Length > 0)
-          {
-              foreach (string value in attrs.Servers)
-              {
-                  attrsSB.Append(value);
-                  attrsSB.Append(',');
-              }
-          }
-          attrsSB.Append(Environment.NewLine);
-          return attrsSB.ToString();
-      }
-    public virtual IRegion<TKey,TVal> CreateRootRegion()
-    {
-      return CreateRootRegion(null);
-    }
-
-    public virtual IRegion<TKey, TVal> CreateRootRegion(string regionName)
-    {
-      string rootRegionData = GetStringValue("regionSpec");
-      return CreateRootRegion(regionName, rootRegionData);
-    }
-
-    public virtual IRegion<TKey, TVal> CreateRootRegion(string regionName,
-      string rootRegionData)
-    {
-      string tagName = GetStringValue("TAG");
-      string endpoints = Util.BBGet(JavaServerBB, EndPointTag + tagName)
-        as string;
-      return CreateRootRegion(regionName, rootRegionData, endpoints);
-    }
-
-    public virtual IRegion<TKey, TVal> CreateRootRegion(string regionName,
-      string rootRegionData, string endpoints)
-    {
-      if (rootRegionData != null && rootRegionData.Length > 0)
-      {
-        string rootRegionName;
-        if (regionName == null || regionName.Length == 0)
-        {
-          rootRegionName = GetRegionName(rootRegionData);
-        }
-        else
-        {
-          rootRegionName = regionName;
-        }
-        if (rootRegionName != null && rootRegionName.Length > 0)
-        {
-          IRegion<TKey, TVal> region;
-          if ((region = CacheHelper<TKey, TVal>.GetRegion(rootRegionName)) == null)
-          {
-            Properties<string,string> dsProps = new Properties<string,string>();
-            GetClientSecurityProperties(ref dsProps, rootRegionName); 
-            
-            // Check for any setting of heap LRU limit
-            int heapLruLimit = GetUIntValue(HeapLruLimitKey);
-            if (heapLruLimit > 0)
-            {
-              dsProps.Insert("heap-lru-limit", heapLruLimit.ToString());
-            }
-            string conflateEvents = GetStringValue(ConflateEventsKey);
-            if (conflateEvents != null && conflateEvents.Length > 0)
-            {
-              dsProps.Insert("conflate-events", conflateEvents);
-            }
-            
-            ResetKey("sslEnable");
-            bool isSslEnable = GetBoolValue("sslEnable");
-            if (isSslEnable)
-            {
-              dsProps.Insert("ssl-enabled", "true");
-              string keyStorePath = Util.GetFwkLogDir(Util.SystemType) + "/data/keystore";
-              string pubkey = keyStorePath + "/client_truststore.pem";
-              string privkey = keyStorePath + "/client_keystore.pem";
-              dsProps.Insert("ssl-keystore", privkey);
-              dsProps.Insert("ssl-truststore", pubkey);
-            }
-            //Properties rootAttrs = GetNewRegionAttributes(rootRegionData);
-            // Check if this is a thin-client region; if so set the endpoints
-            RegionFactory rootAttrs = null; 
-            //RegionFactory rootAttrs = CacheHelper<TKey, TVal>.DCache.CreateRegionFactory(RegionShortcut.PROXY);
-            string m_isPool = null;
-              //SetRegionAttributes(rootAttrs, rootRegionData, ref m_isPool);
-            int redundancyLevel = 0;
-            redundancyLevel = GetUIntValue(RedundancyLevelKey);
-            //string m_isPool = rootAttrs.Find("pool-name");
-            string mode = Util.GetEnvironmentVariable("POOLOPT");
-            if (endpoints != null && endpoints.Length > 0)
-            {
-              //redundancyLevel = GetUIntValue(RedundancyLevelKey);
-              //if (redundancyLevel > 0)
-              //{
-                if (mode == "poolwithendpoints" || mode == "poolwithlocator" )//|| m_isPool != null)
-                {
-                  FwkInfo("Setting the pool-level configurations");
-                  CacheHelper<TKey, TVal>.InitConfigPool(dsProps);
-                }
-                try
-                {
-                    rootAttrs = CacheHelper<TKey, TVal>.DCache.CreateRegionFactory(RegionShortcut.PROXY);
-                }
-                catch (Exception e)
-                {
-                    FwkException("GOT this {0}",e.Message);
-                }
-              FwkInfo("Creating region factory");
-              SetRegionAttributes(rootAttrs, rootRegionData, ref m_isPool);
-            
-            }
-            rootAttrs = CreatePool(rootAttrs, redundancyLevel);
-            ResetKey("NumberOfRegion");
-            int numRegions = GetUIntValue("NumberOfRegion");
-            if (numRegions < 1)
-              numRegions = 1;
-            for (int i = 0; i < numRegions; i++)
-            {
-              if(i>0)
-               region = CacheHelper<TKey, TVal>.CreateRegion(rootRegionName+"_"+i, rootAttrs);
-              else
-               region = CacheHelper<TKey, TVal>.CreateRegion(rootRegionName, rootAttrs);
-            }
-            Apache.Geode.Client.RegionAttributes<TKey, TVal> regAttr = region.Attributes;
-            FwkInfo("Region attributes for {0}: {1}", rootRegionName,
-              CacheHelper<TKey, TVal>.RegionAttributesToString(regAttr));
-          }
-          return region;
-        }
-      }
-      return null;
-    }
-    private void ParseEndPoints(string ep, bool isServer, int redundancyLevel)
-    {
-      string poolName = "_Test_Pool";
-      PoolFactory pf = CacheHelper<TKey, TVal>.DCache.GetPoolFactory();
-      string[] eps = ep.Split(',');
-      foreach (string endpoint in eps)
-      {
-        string hostName = endpoint.Split(':')[0];
-        int portNum = int.Parse(endpoint.Split(':')[1]);
-        if (isServer)
-        {
-          FwkInfo("adding pool host port for server");
-          pf.AddServer(hostName, portNum);
-        }
-        else
-        {
-          FwkInfo("adding pool host port for server");
-          pf.AddLocator(hostName, portNum);
-        }
-      }
-
-      pf.SetSubscriptionEnabled(true);
-
-      ResetKey("multiUserMode");
-      bool multiUserMode = GetBoolValue("multiUserMode");
-      if (multiUserMode)
-      {
-        pf.SetMultiuserAuthentication(true);
-        FwkInfo("MultiUser Mode is set to true");
-      }
-      else
-      {
-        pf.SetMultiuserAuthentication(false);
-        FwkInfo("MultiUser Mode is set to false");
-      }
-      pf.SetFreeConnectionTimeout(TimeSpan.FromMilliseconds(180000));
-      pf.SetReadTimeout(TimeSpan.FromMilliseconds(180000));
-      pf.SetMinConnections(20);
-      pf.SetMaxConnections(30);
-
-      if (redundancyLevel > 0)
-        pf.SetSubscriptionRedundancy(redundancyLevel);
-      if (CacheHelper<TKey, TVal>.DCache.GetPoolManager().Find(poolName) == null)
-      {
-        Pool pool = pf.Create(poolName);
-        FwkInfo("Pool attributes are {0}:", PoolAttributesToString(pool));
-      }
-      FwkInfo("Create Pool complete with poolName= {0}", poolName);
-    }
-   
-    public virtual RegionFactory CreatePool(RegionFactory attr, int redundancyLevel)
-    {
-      string mode = Util.GetEnvironmentVariable("POOLOPT");
-      if (mode == "poolwithendpoints")
-      {
-        string EndPoints = Util.BBGet(JavaServerBB, EndPointTag) as string;
-        ParseEndPoints(EndPoints, true, redundancyLevel);
-        attr = attr.SetPoolName("_Test_Pool");
-      }
-      else if (mode == "poolwithlocator")
-      {
-        string locatorAddress = (string)Util.BBGet(string.Empty, "LOCATOR_ADDRESS_POOL");
-        ParseEndPoints(locatorAddress, false, redundancyLevel);
-        attr = attr.SetPoolName("_Test_Pool");
-      }
-      return attr;
-    }
-   
-    // TODO: format an appropriate line for logging.
-    public virtual void SetTaskRunInfo(string regionTag, string taskName,
-      int numKeys, int numClients, int valueSize, int numThreads)
-    {
-      m_taskData = new FwkTaskData(regionTag, taskName, numKeys, numClients,
-        valueSize, numThreads);
-    }
-
-    public virtual void AddTaskRunRecord(int iters, TimeSpan elapsedTime)
-    {
-      double opsPerSec = iters / elapsedTime.TotalSeconds;
-      double micros = elapsedTime.TotalMilliseconds * 1000;
-      string recordStr = string.Format("{0} -- {1}ops/sec, {2} ops, {3} micros",
-        m_taskData.GetLogString(), opsPerSec, iters, micros);
-      lock (((ICollection)m_taskRecords).SyncRoot)
-      {
-        m_taskRecords.Add(recordStr);
-      }
-      Util.RawLog(string.Format("[PerfSuite] {0}{1}", recordStr,
-        Environment.NewLine));
-      Util.RawLog(string.Format("[PerfData],{0},{1},{2},{3},{4}{5}",
-        m_taskData.GetCSVString(), opsPerSec, iters, micros,
-        DateTime.Now.ToString("G"), Environment.NewLine));
-    }
-
-    public virtual void RunTask(ClientTask task, int numThreads,
-      int iters, int timedInterval, int maxTime, object data)
-    {
-      ClientBase client = null;
-      try
-      {
-        if (numThreads > 1)
-        {
-          client = ClientGroup.Create(UnitThread.Create, numThreads);
-        }
-        else
-        {
-          client = new UnitThread();
-        }
-        UnitFnMethod<UnitFnMethod<int, object>, int, object> taskDeleg =
-          new UnitFnMethod<UnitFnMethod<int, object>, int, object>(
-          client.Call<int, object>);
-        task.StartRun();
-        IAsyncResult taskRes = taskDeleg.BeginInvoke(
-          task.DoTask, iters, data, null, null);
-        if (timedInterval > 0)
-        {
-          System.Threading.Thread.Sleep(timedInterval);
-          task.EndRun();
-        }
-        if (maxTime <= 0)
-        {
-          taskRes.AsyncWaitHandle.WaitOne();
-        }
-        else if (!taskRes.AsyncWaitHandle.WaitOne(maxTime, false))
-        {
-          throw new ClientTimeoutException("RunTask() timed out.");
-        }
-        taskDeleg.EndInvoke(taskRes);
-        task.EndRun();
-      }
-      finally
-      {
-        if (client != null)
-        {
-          client.Dispose();
-        }
-      }
-    }
-
-    public virtual void EndTask()
-    {
-      lock (((ICollection)m_taskRecords).SyncRoot)
-      {
-        if (m_taskRecords.Count > 0)
-        {
-          StringBuilder summarySB = new StringBuilder();
-          foreach (string taskRecord in m_taskRecords)
-          {
-            summarySB.Append(Environment.NewLine + '\t' + taskRecord);
-          }
-          FwkInfo("TIMINGS:: Summary: {0}", summarySB.ToString());
-          m_taskRecords.Clear();
-        }
-      }
-      ClearCachedKeys();
-      PopTaskName();
-    }
-
-    public QueryService CheckQueryService()
-    {
-      string mode = Util.GetEnvironmentVariable("POOLOPT");
-      Pool/*<TKey, TVal>*/ pool = CacheHelper<TKey, TVal>.DCache.GetPoolManager().Find("_Test_Pool");
-      return pool.GetQueryService();
-    }
-
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/NewFwkLib.csproj.in b/tests/cli/NewFwkLib/NewFwkLib.csproj.in
deleted file mode 100644
index 71abeff..0000000
--- a/tests/cli/NewFwkLib/NewFwkLib.csproj.in
+++ /dev/null
@@ -1,266 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-	<CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-	<CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{3DAA5FF5-9FA3-3543-9293-7197636A16C3}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Apache.Geode.Client.FwkLib</RootNamespace>
-    <AssemblyName>NewFwkLib</AssemblyName>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <Optimize>false</Optimize>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>618</NoWarn>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="nunit.framework">
-      <HintPath>${NUNIT}\bin\framework\nunit.framework.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\clicache\src\Apache.Geode.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>   
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\DUnitFramework\DUnitFramework.csproj">
-      <Project>{796727E8-3A6A-46BE-A2DB-584A4774CD51}</Project>
-      <Name>DUnitFramework</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\FwkUtil\FwkUtil.csproj">
-      <Project>{0DDB5AAF-C707-4F65-9000-659A24504D36}</Project>
-      <Name>FwkUtil</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\PdxClassLibrary\PdxClassLibrary.csproj">
-      <Project>{10613802-A371-4C27-8F66-CE79BFCAC3F2}</Project>
-      <Name>PdxClassLibrary</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\PdxVersion1Lib\PdxVersion1Lib.csproj">
-      <Project>{97F9965D-6B3D-44F6-92B3-5880A3C7178E}</Project>
-      <Name>PdxVersion1Lib</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\PdxVersion2Lib\PdxVersion2Lib.csproj">
-      <Project>{5055633B-6D1C-488D-B934-1AC482C915F7}</Project>
-      <Name>PdxVersion2Lib</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\QueryHelper\QueryWrapper.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-      <Name>QueryWrapper</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\SecurityUtil\SecurityUtil.csproj">
-      <Project>{29CFC13C-1D6C-4FE8-B56E-A5E7BA7F849F}</Project>
-      <Name>SecurityUtil</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\CacheHelper.cs">
-      <Link>CacheHelper.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\FwkTest.cs">
-      <Link>FwkTest.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\DeltaTest\DeltaClientValidationListener.cs">
-      <Link>DeltaTest\DeltaClientValidationListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\DeltaTest\DeltaTest.cs">
-      <Link>DeltaTest\DeltaTest.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\PdxTest\PdxTests.cs">
-      <Link>PdxTest\PdxTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\PerfTest\DupChecker.cs">
-      <Link>PerfTest\DupChecker.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\PerfTest\LatencyListener.cs">
-      <Link>PerfTest\LatencyListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\PerfTest\PerfTasks.cs">
-      <Link>PerfTest\PerfTasks.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\PerfTest\PerfTestCacheListener.cs">
-      <Link>PerfTest\PerfTestCacheListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\PerfTest\PerfTests.cs">
-      <Link>PerfTest\PerfTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\CacheServer.cs">
-      <Link>CacheServer.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\DurableTest\DurableClientTests.cs">
-      <Link>DurableTest\DurableClientTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\DurableTest\DurableListener.cs">
-      <Link>DurableTest\DurableListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\DurableTest\DurablePerfListener.cs">
-      <Link>DurableTest\DurablePerfListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\FunctionExecution\FunctionExecution.cs">
-      <Link>FunctionExecution\FunctionExecution.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\FunctionExecution\MyResultCollector.cs">
-      <Link>FunctionExecution\MyResultCollector.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\FwkTask.cs">
-      <Link>FwkTask.cs</Link>
-    </Compile>
-    <!--Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\EventTest\ETCacheListener.cs">
-      <Link>EventTest\ETCacheListener.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\EventTest\ETCacheLoader.cs">
-      <Link>EventTest\ETCacheLoader.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\EventTest\ETCacheWriter.cs">
-      <Link>EventTest\ETCacheWriter.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\EventTest\EventTasks.cs">
-      <Link>EventTest\EventTasks.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\EventTest\EventTests.cs">
-      <Link>EventTest\EventTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\QueryTest\QueryTests.cs">
-      <Link>QueryTest\QueryTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\SecurityTest\Security.cs">
-      <Link>SecurityTest\Security.cs</Link>
-    </Compile-->
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\QueryTest\QueryTests.cs">
-      <Link>QueryTest\QueryTests.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\ResumableTx\ResumableTx.cs">
-      <Link>ResumableTx\ResumableTx.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\ResumableTx\TxInfo.cs">
-      <Link>ResumableTx\TxInfo.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewFwkLib\Utils.cs">
-      <Link>Utils.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewTestObject\DeltaTestImpl.cs">
-      <Link>DeltaTest\DeltaTestImpl.cs</Link>
-    </Compile>
-
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewTestObject\PdxAutoSerializerObj.cs">
-      <Link>PdxTest\PdxAutoSerializerObj.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewTestObject\Portfolio.cs">
-      <Link>QueryTest\Portfolio.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewTestObject\PortfolioPdx.cs">
-      <Link>QueryTest\PortfolioPdx.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewTestObject\Position.cs">
-      <Link>QueryTest\Position.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewTestObject\PositionPdx.cs">
-      <Link>QueryTest\PositionPdx.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\NewTestObject\TestObject1.cs">
-      <Link>DeltaTest\TestObject1.cs</Link>
-    </Compile>
-   <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\QueryHelper\QueryHelperN.cs">
-      <Link>QueryTest\QueryHelperN.cs</Link>
-    </Compile>
-  </ItemGroup>
-  <ItemGroup>
-    <Folder Include="DurableTest\" />
-    <Folder Include="FunctionExecution\" />
-    <Folder Include="PerfTest\" />
-    <Folder Include="ResumableTx\" />
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/tests/cli/NewFwkLib/PdxTest/PdxTests.cs b/tests/cli/NewFwkLib/PdxTest/PdxTests.cs
deleted file mode 100644
index 9d93468..0000000
--- a/tests/cli/NewFwkLib/PdxTest/PdxTests.cs
+++ /dev/null
@@ -1,3067 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Collections;
-using System.Collections.ObjectModel;
-using System.Text;
-using System.Threading;
-using System.Reflection;
-using PdxTests;
-
-
-namespace Apache.Geode.Client.FwkLib
-{
-    using Apache.Geode.DUnitFramework;
-    using Apache.Geode.Client.Tests;
-    using Apache.Geode.Client;
-    using QueryCategory = Apache.Geode.Client.Tests.QueryCategory;
-    using QueryStrings = Apache.Geode.Client.Tests.QueryStrings;
-    using QueryStatics = Apache.Geode.Client.Tests.QueryStatics;
-    using System.IO;
-
-    public class PDXSilenceListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>
-    {
-        long currentTimeInMillies()
-        {
-            long curruntMillis = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-            return curruntMillis;
-        }
-        public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-        {
-
-            Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-        }
-        public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-        {
-            Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-        }
-        public override void AfterDestroy(EntryEvent<TKey, TVal> ev)
-        {
-            Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-        }
-        public override void AfterInvalidate(EntryEvent<TKey, TVal> ev)
-        {
-            Util.BBSet("ListenerBB", "lastEventTime", currentTimeInMillies());
-        }
-    }
-    public class PDXMyCqListener<TKey, TResult> : ICqListener<TKey, TResult>
-    {
-        private UInt32 m_updateCnt;
-        private UInt32 m_createCnt;
-        private UInt32 m_destroyCnt;
-        private UInt32 m_eventCnt;
-
-        public PDXMyCqListener()
-        {
-            m_updateCnt = 0;
-            m_createCnt = 0;
-            m_destroyCnt = 0;
-            m_eventCnt = 0;
-        }
-
-        public UInt32 NumInserts()
-        {
-            return m_createCnt;
-        }
-
-        public UInt32 NumUpdates()
-        {
-            return m_updateCnt;
-        }
-
-        public UInt32 NumDestroys()
-        {
-            return m_destroyCnt;
-        }
-
-        public UInt32 NumEvents()
-        {
-            return m_eventCnt;
-        }
-
-        public virtual void UpdateCount(CqEvent<TKey, TResult> ev)
-        {
-            m_eventCnt++;
-            CqOperation opType = ev.getQueryOperation();
-            if (opType == CqOperation.OP_TYPE_CREATE)
-            {
-                m_createCnt++;
-            }
-            else if (opType == CqOperation.OP_TYPE_UPDATE)
-            {
-                m_updateCnt++;
-            }
-            else if (opType == CqOperation.OP_TYPE_DESTROY)
-            {
-                m_destroyCnt++;
-            }
-
-        }
-        public virtual void OnError(CqEvent<TKey, TResult> ev)
-        {
-            UpdateCount(ev);
-        }
-
-        public virtual void OnEvent(CqEvent<TKey, TResult> ev)
-        {
-            UpdateCount(ev);
-        }
-
-        public virtual void Close()
-        {
-        }
-    }
-    public class PdxEntryTask<TKey, TVal> : ClientTask
-    {
-        #region Private members
-        /*
-        private IRegion<TKey, TVal> m_region;
-        private int m_MaxKeys;
-        private List<IDictionary<TKey, TVal>> m_maps;
-        private Int32 m_create;
-        private Int32 m_update;
-        private Int32 m_destroy;
-        private Int32 m_invalidate;
-        private Int32 m_cnt;
-        bool m_isDestroy;
-        private object CLASS_LOCK = new object();
-        */
-        private IRegion<TKey, TVal> m_region;
-        private int m_MaxKeys;
-        private static bool m_istransaction = false;
-        private static bool isSerialExecution = false;
-        protected static bool isEmptyClient = false;  // true if this is a bridge client with empty dataPolicy
-        protected static bool isThinClient = false; // true if this is a bridge client with eviction to keep it small
-        private static Dictionary<TKey, TVal> regionSnapshot = null;
-        private static List<TKey> destroyedKeys = null;// = new List<TKey>();
-        private static int keyCount = 0;
-        private static string m_sharePath;
-        private Int32 create;
-        private Int32 update;
-        private Int32 destroy;
-        private Int32 invalidate;
-        private Int32 localdestroy;
-        private Int32 localinvalidate;
-        private Int32 putall;
-        private Int32 get;
-        private string m_objectType;
-        private int m_versionNum;
-        private object CLASS_LOCK = new object();
-        #endregion
-
-        public PdxEntryTask(IRegion<TKey, TVal> region, int keyCnt,
-            Dictionary<TKey, TVal> maps, List<TKey> listval, bool serialexe,
-            string objecttype, int versionnum)
-            : base()
-        {
-            m_region = region;
-            m_MaxKeys = keyCnt;
-            regionSnapshot = maps;
-            destroyedKeys = listval;
-            isSerialExecution = serialexe;
-            create = 0;
-            update = 0;
-            destroy = 0;
-            invalidate = 0;
-            localdestroy = 0;
-            localinvalidate = 0;
-            putall = 0;
-            get = 0;
-            m_objectType = objecttype;
-            m_versionNum = versionnum;
-
-        }
-        protected TVal createIpdxInstance()
-        {
-            PdxType pt = new PdxType();
-
-            IPdxInstanceFactory pif = CacheHelper<TKey, TVal>.DCache.CreatePdxInstanceFactory("PdxType");
-
-            pif.WriteInt("m_int32", pt.Int32);
-            pif.WriteString("m_string", pt.PString);
-            pif.WriteObject("m_arraylist", pt.Arraylist);
-            pif.WriteChar("m_char", pt.Char);
-            pif.WriteBoolean("m_bool", pt.Bool);
-            pif.WriteByte("m_sbyte", pt.Sbyte);
-            pif.WriteByte("m_byte", pt.Byte);
-            pif.WriteShort("m_int16", pt.Int16);
-            pif.WriteByteArray("m_byteArray", pt.ByteArray);
-            pif.WriteLong("m_long", pt.Long);
-            pif.WriteFloat("m_float", pt.Float);
-            pif.WriteDouble("m_double", pt.Double);
-            pif.WriteBooleanArray("m_boolArray", pt.BoolArray);
-            pif.WriteByteArray("m_sbyteArray", pt.SbyteArray);
-            pif.WriteCharArray("m_charArray", pt.CharArray);
-            pif.WriteDate("m_dateTime", pt.DateTime);
-            pif.WriteShortArray("m_int16Array", pt.Int16Array);
-            pif.WriteIntArray("m_int32Array", pt.Int32Array);
-            pif.WriteLongArray("m_longArray", pt.LongArray);
-            pif.WriteFloatArray("m_floatArray", pt.FloatArray);
-            pif.WriteDoubleArray("m_doubleArray", pt.DoubleArray);
-            pif.WriteArrayOfByteArrays("m_byteByteArray", pt.ByteByteArray);
-            pif.WriteStringArray("m_stringArray", pt.StringArray);
-            pif.WriteObject("m_map", pt.Map);
-            pif.WriteObject("m_hashtable", pt.Hashtable);
-            pif.WriteObject("m_vector", pt.Vector);
-            pif.WriteObject("m_chs", pt.Chs);
-            pif.WriteObject("m_clhs", pt.Clhs);
-            pif.WriteInt("m_uint32", pt.Uint32);
-            pif.WriteLong("m_ulong", pt.Ulong);
-            pif.WriteShort("m_uint16", pt.Uint16);
-            pif.WriteIntArray("m_uint32Array", pt.Uint32Array);
-            pif.WriteLongArray("m_ulongArray", pt.UlongArray);
-            pif.WriteShortArray("m_uint16Array", pt.Uint16Array);
-            pif.WriteByteArray("m_byte252", pt.Byte252);
-            pif.WriteByteArray("m_byte253", pt.Byte253);
-            pif.WriteByteArray("m_byte65535", pt.Byte65535);
-            pif.WriteByteArray("m_byte65536", pt.Byte65536);
-            pif.WriteObject("m_pdxEnum", pt.PdxEnum);
-
-            pif.WriteObject("m_address", pt.AddressArray);
-            pif.WriteObjectArray("m_objectArray", pt.ObjectArray);
-            IPdxInstance pi = pif.Create();
-            return (TVal)(object)pi;
-        }
-        private TVal GetValue()
-        {
-            return GetValue(null);
-        }
-
-        private TVal GetValue(object value)
-        {
-            TVal tmpValue = default(TVal);
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("valueSizes");
-            int size = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("valueSizes");
-            StringBuilder builder = new StringBuilder();
-            Random random = new Random();
-            char ch;
-            for (int j = 0; j < size; j++)
-            {
-                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
-                builder.Append(ch);
-            }
-            string sharedpath = (string)Util.BBGet("SharedPath", "sharedDir");
-            m_sharePath = Path.Combine(sharedpath ,"framework/csharp/bin");
-            if (typeof(TVal) == typeof(string))
-            {
-                tmpValue = (TVal)(object)builder.ToString();
-            }
-            else if (typeof(TVal) == typeof(byte[]))
-            {
-                tmpValue = (TVal)(object)(Encoding.ASCII.GetBytes(builder.ToString()));
-            }
-            else if (m_objectType != null)
-            {
-                if (m_objectType.Equals("PdxVersioned") && m_versionNum == 1)
-                {
-                    PdxTests<TKey,TVal>.m_pdxVersionOneAsm = Assembly.LoadFrom(Path.Combine(m_sharePath ,"PdxVersion1Lib.dll"));
-                    Type pt = PdxTests<TKey,TVal>.m_pdxVersionOneAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-                    tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, new object[] { value.ToString() });
-                }
-                else if (m_objectType.Equals("PdxVersioned") && m_versionNum == 2)
-                {
-                    PdxTests<TKey, TVal>.m_pdxVersionTwoAsm = Assembly.LoadFrom(Path.Combine(m_sharePath, "PdxVersion2Lib.dll"));
-                    Type pt = PdxTests<TKey, TVal>.m_pdxVersionTwoAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-                    tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, new object[] { value.ToString() });
-                }
-                else if (m_objectType.Equals("Nested"))
-                {
-
-                    tmpValue = (TVal)(object)new NestedPdx();
-                }
-                else if (m_objectType.Equals("PdxType"))
-                {
-                    tmpValue = (TVal)(object)new PdxType();
-                }
-                else if (m_objectType.Equals("PdxInstanceFactory"))
-                {
-
-                    tmpValue = createIpdxInstance();
-                }
-                else if (m_objectType.Equals("AutoSerilizer"))
-                {
-                    tmpValue = (TVal)(object)new SerializePdx1(true);
-                }
-            }
-            else
-                tmpValue = (TVal)(object)value;
-            return tmpValue;
-
-        }
-        protected void verifyContainsKey(IRegion<TKey, TVal> m_region, TKey key, bool expected)
-        {
-            bool containsKey = false;
-            if (isEmptyClient || m_istransaction)
-            {
-                containsKey = m_region.ContainsKey(key);
-            }
-            else
-            {
-                containsKey = m_region.GetLocalView().ContainsKey(key);
-            }
-            if (containsKey != expected)
-            {
-                throw new Exception("Expected ContainsKey() for " + key + " to be " + expected +
-                          " in " + m_region.FullPath + ", but it is " + containsKey);
-            }
-        }
-
-        protected void verifyContainsValueForKey(IRegion<TKey, TVal> m_region, TKey key, bool expected)
-        {
-
-           bool containsValueForKey = false;
-            if (isEmptyClient || m_istransaction)
-                containsValueForKey = m_region.ContainsValueForKey(key);
-            else
-                containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-            if (containsValueForKey != expected)
-            {
-                throw new Exception("Expected ContainsValueForKey() for " + key + " to be " + expected +
-                          " in " + m_region.FullPath + ", but it is " + containsValueForKey);
-            }
-
-        }
-        protected void verifySize(IRegion<TKey, TVal> m_region, int expectedSize)
-        {
-            int size = 0;
-            if (isEmptyClient || m_istransaction)
-                size = m_region.Count;
-            else
-                size = m_region.GetLocalView().Count;
-            if (size != expectedSize)
-            {
-                if (size < 1000)
-                {
-                    StringBuilder sb = new StringBuilder();
-                    sb.Append("region has wrong size (").Append(size)
-                      .Append(").  Dump of region follows:")
-                      .Append("\n");
-                    ICollection<RegionEntry<TKey, TVal>> regionentry = m_region.GetEntries(false);
-                    foreach (RegionEntry<TKey, TVal> kvp in regionentry)
-                    {
-                        TKey key = kvp.Key;
-                        TVal Value = kvp.Value;
-                        sb.Append(key).Append(") -> ").Append(Value)
-                           .Append("\n");
-                    }
-                    FwkTest<TKey, TVal>.CurrentTest.FwkInfo(sb.ToString());
-                }
-                throw new Exception("Expected size of " + m_region.FullPath + " to be " +
-                   expectedSize + ", but it is " + size);
-            }
-            
-        }
-        
-        protected TKey GetNewKey()
-        {
-                FwkTest<TKey, TVal>.CurrentTest.ResetKey("distinctKeys");
-                int numKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("distinctKeys");
-                String keybuf = String.Format("Key-{0}", keyCount);
-                TKey key = (TKey)(object)(keybuf);
-                keyCount++;
-                return key;
-            
-        }
-        protected TKey GetExistingKey(bool useServerKeys, int index)
-        {
-            IRegion<TKey, TVal> region = m_region;
-            TKey key = default(TKey);
-            TKey[] keys = null;
-            int size = 0;
-            if (useServerKeys)
-            {
-                size = region.Count;
-                keys = (TKey[])region.Keys;
-                index = Util.Rand(0, keys.Length);
-                try
-                {
-                  if (keys.Length > 0)
-                  {
-                    key = keys[index];
-                  }
-                }
-                catch (Exception e) { FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught {0} during GetExistingKey()",e.Message); }
-            }
-            else
-            {
-                size = region.GetLocalView().Count;
-                keys = (TKey[])region.GetLocalView().Keys;
-                index = Util.Rand(0, keys.Length);
-                if (keys.Length > 0)
-                {
-                  key = keys[index];
-                }
-            }
-           
-            return key;
-        }
-        protected void validate(TKey key,TVal value,int beforeSize)
-        {
-            if (isSerialExecution)
-            {
-                if (isEmptyClient)
-                {
-                    if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                    {
-                        verifySize(m_region, 0);
-                    }
-                }
-                else if (isThinClient)
-                {
-                    if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                    {
-                        // new entry should be in the local region
-                        verifyContainsKey(m_region, key, true);
-                        verifyContainsValueForKey(m_region, key, true);
-                    }
-                }
-                else
-                { // region has all keys/values
-                    verifyContainsKey(m_region, key, true);
-                    verifyContainsValueForKey(m_region, key, true);
-                    verifySize(m_region, beforeSize);
-                }
-                regionSnapshot[key] = value;
-                destroyedKeys.Remove(key);
-            }
-        }
-        protected void addEntry(IRegion<TKey, TVal> m_region, int index)
-        {
-                object keybuf = null;
-                if (typeof(TKey) == typeof(int))
-                    keybuf = (int)(object)index;
-                else
-                keybuf = String.Format("Key-{0}", index);
-                TKey key = (TKey)(object)(keybuf);
-                TVal value = GetValue(key);
-                int beforeSize = 0;
-                if (isEmptyClient || m_istransaction)
-                    beforeSize = m_region.Count;
-                else
-                    beforeSize = m_region.GetLocalView().Count;
-
-               if (!m_region.ContainsKey(key))
-                m_region.Add(key, value);
-               else
-                {
-                    value = GetValue(("updated_" + key));
-                    m_region[key] = value;
-                }
-                // validation
-                validate(key,value,beforeSize+1);
-            
-       
-        }
-        
-        protected void updateEntry(IRegion<TKey, TVal> r,int index)
-        {
-            TKey key = GetExistingKey(isEmptyClient || isThinClient, index);
-            if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-            {
-                int size = r.Count;
-                if (isSerialExecution && (size != 0))
-                    throw new Exception("getExistingKey returned " + key + ", but region size is " + size);
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("updateEntry: No keys in region");
-                return;
-            }
-            int beforeSize = 0;
-            if (isEmptyClient || m_istransaction)
-                beforeSize = r.Count;
-            else
-                beforeSize = r.GetLocalView().Count;
-            TVal value = GetValue(("updated_" + key));
-            r[key] = value;
-
-            // validation
-            // cannot validate return value from put due to bug 36436; in peer configurations
-            // we do not make any guarantees about the return value
-            validate(key,value,beforeSize);
-           
-        }
-        
-        protected void invalidateEntry(IRegion<TKey, TVal> m_region, bool isLocalInvalidate, int index)
-        {
-            int beforeSize = 0;
-            if (isEmptyClient || m_istransaction)
-                beforeSize = m_region.Count;
-            else
-                beforeSize = m_region.GetLocalView().Count;
-            TKey key = GetExistingKey(isEmptyClient || isThinClient, index);
-            if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-            {
-                if (isSerialExecution && (beforeSize != 0))
-                    throw new Exception("getExistingKey returned " + key + ", but region size is " + beforeSize);
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("invalidateEntry: No keys in region");
-                return;
-            }
-            bool containsKey = m_region.GetLocalView().ContainsKey(key);
-            bool containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-            try
-            {
-                if (isLocalInvalidate)
-                { // do a local invalidate
-                    m_region.GetLocalView().Invalidate(key);
-                }
-                else
-                { // do a distributed invalidate
-                    m_region.Invalidate(key);
-                }
-
-                // validation
-                if (isSerialExecution)
-                {
-                    if (isEmptyClient)
-                    {
-                        if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                        {
-                            verifySize(m_region, 0);
-                        }
-                    }
-                    else if (isThinClient)
-                    { // we have eviction
-                        if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                        {
-                            verifySize(m_region, beforeSize);
-                        }
-                    }
-                    else
-                    { // region has all keys/values
-                        verifyContainsKey(m_region, key, true);
-                        verifyContainsValueForKey(m_region, key, false);
-                        verifySize(m_region, beforeSize);
-                    }
-                    regionSnapshot[key] = default(TVal);
-                    //regionSnapshot.Remove(key);
-                    destroyedKeys.Remove(key);
-                }
-            }
-            catch (EntryNotFoundException e)
-            {
-                if (isSerialExecution)
-                    throw new Exception(e.StackTrace);
-                else
-                {
-                    Util.Log("Caught {0} (expected with concurrent execution); continuing with test", e);
-                    return;
-                }
-            }
-            catch (Exception e)
-            {
-                FwkTest<TKey, TVal>.CurrentTest.FwkException("Invalide operation caught {0}",e.Message);
-            }
-        }
-        /** Get an existing key in the given region if one is available,
-         *  otherwise get a new key. 
-         *
-         *  @param aRegion The region to use for getting an entry.
-         */
-        protected void getKey(IRegion<TKey, TVal> aRegion,int index)
-        {
-            TKey key = GetExistingKey(isEmptyClient || isThinClient,index);
-            if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-            { // no existing keys; get a new key then
-                int size = aRegion.Count;
-                if (isSerialExecution && (size != 0))
-                    throw new Exception("getExistingKey returned " + key + ", but region size is " + size);
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("getKey: No keys in region");
-                return;
-            }
-            int beforeSize = 0;
-            if (isEmptyClient || m_istransaction)
-                beforeSize = aRegion.Count;
-            else
-                beforeSize = aRegion.GetLocalView().Count;
-            bool beforeContainsValueForKey = aRegion.ContainsValueForKey(key);
-            bool beforeContainsKey = aRegion.ContainsKey(key);
-            TVal anObj = default(TVal);
-            try
-            {
-                anObj = (TVal)aRegion[key];
-            }
-            catch (Apache.Geode.Client.KeyNotFoundException)
-            {
-                if (!EqualityComparer<TVal>.Default.Equals(anObj, default(TVal)))
-                {
-                    throw new Apache.Geode.Client.KeyNotFoundException();
-                }
-
-            }
-
-            // validation 
-            if (isSerialExecution)
-            {
-                if (isEmptyClient)
-                {
-                    if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                    {
-                        verifySize(aRegion, 0);
-                    }
-                }
-                else if (isThinClient)
-                { // we have eviction
-                    if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                    {
-                        verifyContainsKey(aRegion, key, true);
-                    }
-                }
-                else
-                { // we have all keys/values
-                    verifyContainsKey(aRegion, key, true);
-                    verifyContainsValueForKey(aRegion, key, (beforeContainsValueForKey));
-
-                    // check the expected value of the get
-                    TVal actualValue = anObj;
-                    TVal expectedValue = default(TVal);
-                    foreach (KeyValuePair<TKey, TVal> kvp in regionSnapshot)
-                    {
-                        TKey mapkey = kvp.Key;
-
-                        if (key.Equals(mapkey))
-                        {
-                            expectedValue = kvp.Value;
-                            if (!EqualityComparer<TVal>.Default.Equals(actualValue, default(TVal)))
-                            {
-                                if (!actualValue.Equals(expectedValue))
-                                {
-                                    FwkTest<TKey, TVal>.CurrentTest.FwkException("getKey: expected value {0} is not same as actual value {1} for key {2}",
-                                  expectedValue, actualValue, key);
-                                }
-                            }
-                        }
-                    }
-                    verifySize(aRegion, beforeSize);
-                }
-
-                // record the current state
-                // in case the get works like a put because there is a cacheLoader
-                regionSnapshot[key] = anObj;
-                destroyedKeys.Remove(key);
-            }
-        }
-        protected void destroyEntry(IRegion<TKey, TVal> m_region, bool isLocalDestroy, int index)
-        {
-            TKey key = GetExistingKey(isEmptyClient || isThinClient, index);
-            if (EqualityComparer<TKey>.Default.Equals(key, default(TKey)))
-            {
-                int size = m_region.Count;
-                if (isSerialExecution && (size != 0))
-                    throw new Exception("getExistingKey returned " + key + ", but region size is " + size);
-                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("destroyEntry: No keys in region");
-                return;
-            }
-            int beforeSize = 0;
-            if (isEmptyClient || m_istransaction)
-                beforeSize = m_region.Count;
-            else
-                beforeSize = m_region.GetLocalView().Count;
-            try
-            {
-                if (isLocalDestroy)
-                { // do a local invalidate
-                    m_region.GetLocalView().Remove(key);
-                }
-                else
-                { // do a distributed invalidate
-                    m_region.Remove(key);
-                }
-
-                // validation
-                if (isSerialExecution)
-                {
-                    if (isEmptyClient)
-                    {
-                        if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                        {
-                            verifySize(m_region, 0);
-                        }
-                    }
-                    else if (isThinClient)
-                    { // we have eviction
-                        if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                        {
-                            verifyContainsKey(m_region, key, false);
-                            verifyContainsValueForKey(m_region, key, false);
-                            int afterSize = m_region.Count;
-                            if ((afterSize != beforeSize) && (afterSize != beforeSize - 1))
-                            {
-                                throw new Exception("Expected region size " + afterSize + " to be either " +
-                                    beforeSize + " or " + (beforeSize - 1));
-                            }
-                        }
-                    }
-                    else
-                    { // region has all keys/values
-                        verifyContainsKey(m_region, key, false);
-                        verifyContainsValueForKey(m_region, key, false);
-                        verifySize(m_region, beforeSize - 1);
-                    }
-                    regionSnapshot.Remove(key);
-                    destroyedKeys.Add(key);
-                }
-            }
-            catch (EntryNotFoundException e)
-            {
-                if (isSerialExecution)
-                    throw new Exception(e.StackTrace);
-                else
-                {
-                    Util.Log("Caught {0} (expected with concurrent execution); continuing with test", e);
-                    return;
-                }
-            }
-        }
-        protected void putAll(IRegion<TKey, TVal> r, int index)
-        {
-            // determine the number of new keys to put in the putAll
-            int beforeSize = 0;
-            if (isEmptyClient || m_istransaction)
-                beforeSize = r.Count;
-            else
-                beforeSize = r.GetLocalView().Count;
-            int localBeforeSize = r.GetLocalView().Count;
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("numPutAllExistingKeys");
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey("numPutAllNewKeys");
-            int numNewKeysToPut = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("numPutAllNewKeys");
-            // get a map to put
-            IDictionary<TKey, TVal> mapToPut = new Dictionary<TKey, TVal>();
-            int valSize = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("valueSizes");
-            int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-            valSize = ((valSize < minValSize) ? minValSize : valSize);
-            string valBuf = null;
-            valBuf = new string('A', valSize);
-            StringBuilder newKeys = new StringBuilder();
-            for (int i = 0; i < numNewKeysToPut; i++)
-            {
-                TKey key = GetNewKey();
-                TVal value = GetValue(key);
-                mapToPut[key] = value;
-                newKeys.Append(key + " ");
-                if ((i % 10) == 0)
-                {
-                    newKeys.Append("\n");
-                }
-            }
-
-
-            // add existing keys to the map
-            int numPutAllExistingKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("numPutAllExistingKeys");
-            StringBuilder existingKeys = new StringBuilder();
-            if (numPutAllExistingKeys > 0)
-            {
-                for (int i = 0; i < numPutAllExistingKeys; i++)
-                { // put existing keys
-                    TKey key = GetExistingKey(isEmptyClient || isThinClient,i);
-                    TVal anObj = GetValue(key);
-                    mapToPut[key] = anObj;
-                    existingKeys.Append(key + " ");
-                    if (((i + 1) % 10) == 0)
-                    {
-                        existingKeys.Append("\n");
-                    }
-                }
-            }
-            FwkTest<TKey, TVal>.CurrentTest.FwkInfo("PR size is " + beforeSize + ", local region size is " +
-                localBeforeSize + ", map to use as argument to putAll is " +
-                mapToPut.GetType().Name + " containing " + numNewKeysToPut + " new keys and " +
-                numPutAllExistingKeys + " existing keys (updates); total map size is " + mapToPut.Count +
-                "\nnew keys are: " + newKeys + "\n" + "existing keys are: " + existingKeys);
-   
-            // do the putAll
-            FwkTest<TKey, TVal>.CurrentTest.FwkInfo("putAll: calling putAll with map of " + mapToPut.Count + " entries");
-            r.PutAll(mapToPut, TimeSpan.FromSeconds(60));
-
-            FwkTest<TKey, TVal>.CurrentTest.FwkInfo("putAll: done calling putAll with map of " + mapToPut.Count + " entries");
-
-            // validation
-            if (isSerialExecution)
-            {
-                if (isEmptyClient)
-                {
-                    if (!CacheHelper<TKey, TVal>.DCache.CacheTransactionManager.Exists())
-                    {
-                        verifySize(r, 0);
-                    }
-                }
-                else
-                { // we have all keys/values in the local region
-                    verifySize(r, beforeSize + numNewKeysToPut);
-                }
-                foreach (KeyValuePair<TKey, TVal> kvp in regionSnapshot)
-                {
-                    TKey key = kvp.Key;
-                    TVal value = kvp.Value;
-                    if (!isEmptyClient && !isThinClient)
-                    {
-                        verifyContainsKey(r, key, true);
-                        verifyContainsValueForKey(r, key, true);
-                    }
-                    regionSnapshot[key] = value;
-                    destroyedKeys.Remove(key);
-                }
-            }
-        }
-        public override void DoTask(int iters, object data)
-        {
-
-            int offset = Util.Rand(m_MaxKeys);
-            int count = offset;
-            int size = 0;
-            Util.Log("PdxEntryTask::DoTask: starting {0} iterations and maxkey {1} count {2}.", iters, m_MaxKeys, count);
-            isEmptyClient = !(m_region.Attributes.CachingEnabled);
-            isThinClient = m_region.Attributes.CachingEnabled;
-            while (Running && (iters-- != 0))
-            {
-                int idx = count % m_MaxKeys;
-                
-                size = m_region.Count;
-               
-                //FwkTest<TKey, TVal>.CurrentTest.ResetKey("entryOps");
-                string opcode = FwkTest<TKey, TVal>.CurrentTest.GetStringValue("entryOps");
-                Util.Log("OpCode is {0}",opcode);
-                lock (CLASS_LOCK)
-                {
-                    //if (((size < 1) && (opcode != "create")) || (opcode == "create"))
-                    if(opcode == "create")
-                    {
-                        try
-                        {
-                            addEntry(m_region, idx+1);
-                            create++;
-                        }
-                        catch (EntryExistsException e)
-                        {
-                            if (isSerialExecution)
-                        {
-                                FwkTest<TKey, TVal>.CurrentTest.FwkException(e.Message);
-                            }
-                            else
-                                FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Got {0} which is expected with concurrent execution",e.Message);
-                        }
-                    }
-                    else if (opcode == "update")
-                    {
-                        updateEntry(m_region, idx);
-                        update++;
-                    }
-                    else if (opcode == "destroy")
-                    {
-                        destroyEntry(m_region, false, idx);
-                        destroy++;
-                    }
-                    else if (opcode == "localDestroy")
-                    {
-                        destroyEntry(m_region, true, idx);
-                        localdestroy++;
-                    }
-                    else if (opcode == "invalidate")
-                    {
-                        invalidateEntry(m_region, false, idx);
-                        invalidate++;
-                   }
-                    else if (opcode == "localInvalidate")
-                    {
-                        invalidateEntry(m_region, true, idx);
-                        localinvalidate++;
-                    }
-                    else if (opcode == "putAll")
-                    {
-                        putAll(m_region, idx);
-                        putall++;
-                    }
-                    else if (opcode == "get")
-                    {
-                        getKey(m_region, idx);
-                        get++;
-                    }
-                    else
-                    {
-                        FwkTest<TKey, TVal>.CurrentTest.FwkException("PdxEntryTask:DoTask() Invalid operation " +
-                        "specified: {0}", opcode);
-                    }
-                }
-                count++;
-            }
-            Interlocked.Add(ref m_iters, count - offset);
-            FwkTest<TKey, TVal>.CurrentTest.FwkInfo("DoEntryOP: create = {0}, update = {1}, destroy = {2}, localdestroy = {3},"
-                + "invalidate = {4},localinvalidate = {5}, get = {6}, putall = {7} and RegionSize = {8}",
-                create, update, destroy, localinvalidate, invalidate, localinvalidate, get, putall,m_region.Count);
-        }
-
-    }
-
-    public class PdxTypeMapper : IPdxTypeMapper
-    {
-
-        public string ToPdxTypeName(string localTypeName)
-        {
-            return localTypeName;
-        }
-
-        public string FromPdxTypeName(string pdxTypeName)
-        {
-            Util.Log("pdxTypeName = {0}", pdxTypeName);
-            if (pdxTypeName.Equals("PdxTests.PdxVersioned"))
-            {
-               return "PdxVersionTests.PdxVersioned";
-
-            }
-            else if (pdxTypeName.Equals("PdxTests.pdxEnumTest"))
-            {
-               return "PdxVersionTests.pdxEnumTest";
-            }
-            else
-                return pdxTypeName;
-        }
-    }
-
-    public class PdxTests<TKey, TVal> : FwkTest<TKey, TVal>
-    {
-        #region Private constants and statics
-
-        protected const string ClientCount = "clientCount";
-        protected const string TimedInterval = "timedInterval";
-        protected const string DistinctKeys = "distinctKeys";
-        protected const string NumThreads = "numThreads";
-        protected const string ValueSizes = "valueSizes";
-        protected const string KeyType = "keyType";
-        protected const string KeySize = "keySize";
-        private const string RegionName = "regionName";
-        private const string OpsSecond = "opsSecond";
-        private const string EntryCount = "entryCount";
-        private const string WorkTime = "workTime";
-        private const string EntryOps = "entryOps";
-        private const string LargeSetQuery = "largeSetQuery";
-        private const string UnsupportedPRQuery = "unsupportedPRQuery";
-        private const string ObjectType = "objectType";
-        
-        private static Dictionary<string, int> OperationsMap =
-          new Dictionary<string, int>();
-        private static Dictionary<string, int> ExceptionsMap =
-          new Dictionary<string, int>();
-        private static bool m_istransaction = false;
-        private static bool isSerialExecution = false;
-        protected static bool isEmptyClient = false;  // true if this is a bridge client with empty dataPolicy
-        protected static bool isThinClient = false; // true if this is a bridge client with eviction to keep it small
-        private static Dictionary<TKey, TVal> regionSnapshot = null;
-        private static List<TKey> destroyedKeys = null;// = new List<TKey>();
-        public static Assembly m_pdxVersionOneAsm;
-        public static Assembly m_pdxVersionTwoAsm;
-        private static string m_sharePath;
-
-        protected static string objectType = null;
-        protected static int versionnum = 1;
-        #endregion
-
-        #region Private utility methods
-
-        private IRegion<TKey, TVal> GetRegion()
-        {
-            return GetRegion(null);
-        }
-
-        protected IRegion<TKey, TVal> GetRegion(string regionName)
-        {
-            IRegion<TKey, TVal> region;
-            if (regionName == null)
-            {
-                regionName = GetStringValue("regionName");
-            }
-            if (regionName == null)
-            {
-                region = (IRegion<TKey, TVal>)GetRootRegion();
-                if (region == null)
-                {
-                    IRegion<TKey, TVal>[] rootRegions = CacheHelper<TKey, TVal>.DCache.RootRegions<TKey, TVal>();
-                    if (rootRegions != null && rootRegions.Length > 0)
-                    {
-                        region = rootRegions[Util.Rand(rootRegions.Length)];
-                    }
-                }
-            }
-            else
-            {
-                region = CacheHelper<TKey, TVal>.GetRegion(regionName);
-            }
-            return region;
-        }
-
-        private void AddValue(IRegion<TKey, TVal> region, int count, byte[] valBuf)
-        {
-            if (region == null)
-            {
-                FwkSevere("CacheServer::AddValue(): No region to perform add on.");
-                return;
-            }
-            TKey key = (TKey)(object)count.ToString();
-            TVal value = (TVal)(object)valBuf;
-            BitConverter.GetBytes(count).CopyTo(valBuf, 0);
-            BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-            try
-            {
-                region.Add(key, value);
-                //FwkInfo("key: {0}  value: {1}", key, Encoding.ASCII.GetString(value.Value));
-            }
-            catch (Exception ex)
-            {
-                FwkException("CacheServer.AddValue() caught Exception: {0}", ex);
-            }
-        }
-
-        private TKey GetKey(int max)
-        {
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey(ObjectType);
-            string objectType = GetStringValue(ObjectType);
-            QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-            int numSet = 0;
-            int setSize = 0;
-            if (objectType != null && objectType == "Portfolio")
-            {
-                setSize = qh.PortfolioSetSize;
-                numSet = max / setSize;
-                return (TKey)(object)String.Format("port{0}-{1}", Util.Rand(numSet), Util.Rand(setSize));
-            }
-            else if (objectType != null && objectType == "Position")
-            {
-                setSize = qh.PositionSetSize;
-                numSet = max / setSize;
-                return (TKey)(object)String.Format("pos{0}-{1}", Util.Rand(numSet), Util.Rand(setSize));
-            }
-            return (TKey)(object)Util.Rand(max).ToString();
-        }
-
-        private TVal GetUserObject(string objType)
-        {
-            TVal usrObj = default(TVal);
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey(EntryCount);
-            int numOfKeys = GetUIntValue(EntryCount);
-            FwkTest<TKey, TVal>.CurrentTest.ResetKey(ValueSizes);
-            int objSize = GetUIntValue(ValueSizes);
-            QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-            int numSet = 0;
-            int setSize = 0;
-            if (objType != null && objType == "Portfolio")
-            {
-                setSize = qh.PortfolioSetSize;
-                numSet = numOfKeys / setSize;
-                usrObj = (TVal)(object)new Portfolio(Util.Rand(setSize), objSize);
-            }
-            else if (objType != null && objType == "Position")
-            {
-                setSize = qh.PositionSetSize;
-                numSet = numOfKeys / setSize;
-                int numSecIds = Portfolio.SecIds.Length;
-                usrObj = (TVal)(object)new Position(Portfolio.SecIds[setSize % numSecIds], setSize * 100);
-            }
-            return usrObj;
-        }
-
-        private bool AllowQuery(QueryCategory category, bool haveLargeResultset,
-      bool islargeSetQuery, bool isUnsupportedPRQuery)
-        {
-            if (category == QueryCategory.Unsupported)
-            {
-                return false;
-            }
-            else if (haveLargeResultset != islargeSetQuery)
-            {
-                return false;
-            }
-            else if (isUnsupportedPRQuery &&
-                     ((category == QueryCategory.MultiRegion) ||
-                      (category == QueryCategory.NestedQueries)))
-            {
-                return false;
-            }
-            else
-            {
-                return true;
-            }
-        }
-        private void remoteQuery(QueryStrings currentQuery, bool isLargeSetQuery, 
-      bool isUnsupportedPRQuery, int queryIndex,bool isparam,bool isStructSet)
-        {
-            DateTime startTime;
-            DateTime endTime;
-            TimeSpan elapsedTime;
-            var qs = CheckQueryService();
-            if (AllowQuery(currentQuery.Category, currentQuery.IsLargeResultset,
-                  isLargeSetQuery, isUnsupportedPRQuery))
-            {
-                string query = currentQuery.Query;
-                FwkInfo("CacheServer.RunQuery: ResultSet Query Category [{0}], " +
-                  "String [{1}].", currentQuery.Category, query);
-                Query<object> qry = qs.NewQuery<object>(query);
-                object[] paramList = null;
-                if (isparam)
-                {
-                    Int32 numVal = 0;
-                    if (isStructSet)
-                    {
-                        paramList = new object[QueryStatics.NoOfQueryParamSS[queryIndex]];
-
-                        for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParamSS[queryIndex]; ind++)
-                        {
-                            try
-                            {
-                                numVal = Convert.ToInt32(QueryStatics.QueryParamSetSS[queryIndex][ind]);
-                                paramList[ind] = numVal;
-                            }
-                            catch (FormatException)
-                            {
-                                paramList[ind] = (System.String)QueryStatics.QueryParamSetSS[queryIndex][ind];
-                            }
-                        }
-                    }
-                    else
-                    {
-                        paramList = new object[QueryStatics.NoOfQueryParam[queryIndex]];
-                        for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParam[queryIndex]; ind++)
-                        {
-                            try
-                            {
-                                numVal = Convert.ToInt32(QueryStatics.QueryParamSet[queryIndex][ind]);
-                                paramList[ind] = numVal;
-                            }
-                            catch (FormatException)
-                            {
-                                paramList[ind] = (System.String)QueryStatics.QueryParamSet[queryIndex][ind];
-                            }
-                        }
-                    }
-                }
-                ISelectResults<object> results = null;
-                startTime = DateTime.Now;
-                if (isparam)
-                {
-                    results = qry.Execute(paramList, TimeSpan.FromSeconds(600));
-                }
-                else
-                {
-                    results = qry.Execute(TimeSpan.FromSeconds(600));
-                }
-                endTime = DateTime.Now;
-                elapsedTime = endTime - startTime;
-                FwkInfo("CacheServer.RunQuery: Time Taken to execute" +
-                  " the query [{0}]: {1}ms", query, elapsedTime.TotalMilliseconds);
-            }
-        }
-
-        private void RunQuery()
-        {
-            FwkInfo("In CacheServer.RunQuery");
-
-            try
-            {
-                FwkTest<TKey, TVal>.CurrentTest.ResetKey(EntryCount);
-                int numOfKeys = GetUIntValue(EntryCount);
-                QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-                int setSize = qh.PortfolioSetSize;
-                if (numOfKeys < setSize)
-                {
-                    setSize = numOfKeys;
-                }
-                int i = Util.Rand(QueryStrings.RSsize);
-                ResetKey(LargeSetQuery);
-                ResetKey(UnsupportedPRQuery);
-                bool isLargeSetQuery = GetBoolValue(LargeSetQuery);
-                bool isUnsupportedPRQuery = GetBoolValue(UnsupportedPRQuery);
-                QueryStrings currentQuery = QueryStatics.ResultSetQueries[i];
-                remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i, false, false);
-                i = Util.Rand(QueryStrings.SSsize);
-                currentQuery = QueryStatics.StructSetQueries[i];
-                remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i, false, false);
-                i = Util.Rand(QueryStrings.RSPsize);
-                currentQuery = QueryStatics.ResultSetParamQueries[i];
-                remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i, true, false);
-                i = Util.Rand(QueryStrings.SSPsize);
-                currentQuery = QueryStatics.StructSetParamQueries[i];
-                remoteQuery(currentQuery, isLargeSetQuery, isUnsupportedPRQuery, i, true, true);
-            }
-            catch (Exception ex)
-            {
-                FwkException("CacheServer.RunQuery: Caught Exception: {0}", ex);
-            }
-            FwkInfo("CacheServer.RunQuery complete.");
-        }
-
-        private void UpdateOperationsMap(string opCode, int numOps)
-        {
-            UpdateOpsMap(OperationsMap, opCode, numOps);
-        }
-
-        private void UpdateExceptionsMap(string opCode, int numOps)
-        {
-            UpdateOpsMap(ExceptionsMap, opCode, numOps);
-        }
-
-        private void UpdateOpsMap(Dictionary<string, int> map, string opCode,
-      int numOps)
-        {
-            lock (((ICollection)map).SyncRoot)
-            {
-                int currentOps;
-                if (!map.TryGetValue(opCode, out currentOps))
-                {
-                    currentOps = 0;
-                }
-                map[opCode] = currentOps + numOps;
-            }
-        }
-
-        private int GetOpsFromMap(Dictionary<string, int> map, string opCode)
-        {
-            int numOps;
-            lock (((ICollection)map).SyncRoot)
-            {
-                if (!map.TryGetValue(opCode, out numOps))
-                {
-                    numOps = 0;
-                }
-            }
-            return numOps;
-        }
-        private void PutAllOps()
-        {
-            IRegion<TKey, TVal> region = GetRegion();
-            IDictionary<TKey, TVal> map = new Dictionary<TKey, TVal>();
-            int valSize = GetUIntValue(ValueSizes);
-            int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-            valSize = ((valSize < minValSize) ? minValSize : valSize);
-            string valBuf = null;
-            ResetKey(ObjectType);
-            string objectType = GetStringValue(ObjectType);
-            if (objectType != null)
-            {
-                Int32 numSet = 0;
-                Int32 setSize = 0;
-                QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-                TVal port;
-                setSize = qh.PortfolioSetSize;
-                numSet = 200 / setSize;
-                for (int set = 1; set <= numSet; set++)
-                {
-                    for (int current = 1; current <= setSize; current++)
-                    {
-                        port = (TVal)(object)new Portfolio(current, valSize);
-                        string Id = String.Format("port{0}-{1}", set, current);
-                        TKey key = (TKey)(object)Id.ToString();
-                        map.Add(key, port);
-                    }
-                }
-            }
-            else
-            {
-                valBuf = new string('A', valSize);
-                for (int count = 0; count < 200; count++)
-                {
-                    TKey key = (TKey)(object)count.ToString();
-                    TVal value = (TVal)(object)Encoding.ASCII.GetBytes(valBuf);
-                    map.Add(key, value);
-                }
-            }
-            region.PutAll(map, TimeSpan.FromSeconds(60));
-        }
-
-        private void GetAllOps()
-        {
-            IRegion<TKey, TVal> region = GetRegion();
-            List<TKey> keys = new List<TKey>();
-            keys.Clear();
-            for (int count = 0; count < 200; count++)
-            {
-                TKey key = (TKey)(object)count.ToString();
-                keys.Add(key);
-            }
-            IDictionary<TKey, TVal> values = new Dictionary<TKey, TVal>();
-            values.Clear();
-            region.GetAll(keys.ToArray(), values, null, false);
-        }
-        #endregion
-
-        #region Public methods
-        public static ICacheListener<TKey, TVal> CreateSilenceListenerPdx()
-        {
-            return new PDXSilenceListener<TKey, TVal>();
-        }
-        public virtual void DoCreatePool()
-        {
-            FwkInfo("In DoCreatePool()");
-            try
-            {
-                CreatePool();
-            }
-            catch (Exception ex)
-            {
-                FwkException("DoCreatePool() Caught Exception: {0}", ex);
-            }
-            FwkInfo("DoCreatePool() complete.");
-        }
-
-        public virtual void DoCreateRegion()
-        {
-            FwkInfo("In DoCreateRegion()");
-            try
-            {
-                IRegion<TKey, TVal> region = CreateRootRegion();
-                ResetKey("useTransactions");
-                m_istransaction = GetBoolValue("useTransactions");
-                isEmptyClient = !(region.Attributes.CachingEnabled);
-                isThinClient = region.Attributes.CachingEnabled;
-                objectType = GetStringValue(ObjectType);
-                versionnum = GetUIntValue("versionNum");
-                string sharedpath = (string)Util.BBGet("SharedPath", "sharedDir");
-                m_sharePath = Path.Combine(sharedpath , "framework/csharp/bin");
-                if (objectType != null)
-                {
-                    var typeRegistry = CacheHelper<TKey, TVal>.DCache.TypeRegistry;
-                    if (objectType.Equals("PdxVersioned") && versionnum == 1)
-                    {
-                        m_pdxVersionOneAsm = Assembly.LoadFrom(Path.Combine(m_sharePath, "PdxVersion1Lib.dll"));
-                        typeRegistry.RegisterPdxType(registerPdxTypeOne);
-                        typeRegistry.PdxTypeMapper = new PdxTypeMapper();
-                    }
-                    else if (objectType.Equals("PdxVersioned") && versionnum == 2)
-                    {
-                       m_pdxVersionTwoAsm = Assembly.LoadFrom(Path.Combine(m_sharePath, "PdxVersion2Lib.dll"));
-                       typeRegistry.RegisterPdxType(registerPdxTypeTwo);
-                       typeRegistry.PdxTypeMapper = new PdxTypeMapper();
-                    }
-                    else if (objectType.Equals("Nested"))
-                    {
-                        typeRegistry.RegisterPdxType(NestedPdx.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes1.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes2.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes3.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes4.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes5.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes6.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes7.CreateDeserializable);
-                        typeRegistry.RegisterPdxType(PdxTypes8.CreateDeserializable);
-                    }
-                    else if (objectType.Equals("PdxType"))
-                    {
-                        typeRegistry.RegisterPdxType(PdxType.CreateDeserializable);
-                    }
-                    else if (objectType.Equals("AutoSerilizer"))
-                    {
-                        typeRegistry.PdxSerializer = new ReflectionBasedAutoSerializer();
-                    }
-                }
-                isSerialExecution = GetBoolValue("serialExecution");
-                if (isSerialExecution)
-                {
-                    regionSnapshot = new Dictionary<TKey, TVal>();
-                    destroyedKeys = new List<TKey>();
-                }
-                if (region == null)
-                {
-                    FwkException("DoCreateRegion()  could not create region.");
-                }
-
-                FwkInfo("DoCreateRegion()  Created region '{0}'", region.Name);
-            }
-            catch (Exception ex)
-            {
-                FwkException("DoCreateRegion() Caught Exception: {0}", ex);
-            }
-            FwkInfo("DoCreateRegion() complete.");
-        }
-        IPdxSerializable registerPdxTypeOne()
-        {
-            Type pt = m_pdxVersionOneAsm.GetType("PdxVersionTests.PdxVersioned");
-
-            object ob = pt.InvokeMember("CreateDeserializable", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);
-
-            return (IPdxSerializable)ob;
-        }
-        IPdxSerializable registerPdxTypeTwo()
-        {
-            Type pt = m_pdxVersionTwoAsm.GetType("PdxVersionTests.PdxVersioned");
-
-            object ob = pt.InvokeMember("CreateDeserializable", BindingFlags.Default | BindingFlags.InvokeMethod, null, null, null);
-
-            return (IPdxSerializable)ob;
-        }
-        public void DoCloseCache()
-        {
-            FwkInfo("DoCloseCache()  Closing cache and disconnecting from" +
-              " distributed system.");
-            CacheHelper<TKey, TVal>.Close();
-        }
-        public void DoRegisterAllKeys()
-        {
-            FwkInfo("In DoRegisterAllKeys()");
-            try
-            {
-                IRegion<TKey, TVal> region = GetRegion();
-                FwkInfo("DoRegisterAllKeys() region name is {0}", region.Name);
-                bool isDurable = GetBoolValue("isDurableReg");
-                ResetKey("getInitialValues");
-                bool isGetInitialValues = GetBoolValue("getInitialValues");
-                bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-                bool isReceiveValues = true;
-                if (checkReceiveVal)
-                {
-                    ResetKey("receiveValue");
-                    isReceiveValues = GetBoolValue("receiveValue");
-                }
-                region.GetSubscriptionService().RegisterAllKeys(isDurable, isGetInitialValues, isReceiveValues);
-            }
-            catch (Exception ex)
-            {
-                FwkException("DoRegisterAllKeys() Caught Exception: {0}", ex);
-            }
-            FwkInfo("DoRegisterAllKeys() complete.");
-        }
-        public void DoFeed()
-        {
-            FwkInfo("CacheServer.DoFeed() called.");
-
-            int opsSec = GetUIntValue(OpsSecond);
-            opsSec = (opsSec < 1) ? 0 : opsSec;
-
-            int entryCount = GetUIntValue(EntryCount);
-            entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-            int cnt = 0;
-            int valSize = GetUIntValue(ValueSizes);
-            int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-            valSize = ((valSize < minValSize) ? minValSize : valSize);
-            string valBuf = new string('A', valSize);
-
-            IRegion<TKey, TVal> region = GetRegion();
-            PaceMeter pm = new PaceMeter(opsSec);
-            while (cnt++ < entryCount)
-            {
-                AddValue(region, cnt, Encoding.ASCII.GetBytes(valBuf));
-                pm.CheckPace();
-            }
-        }
-
-        // ----------------------- begin pdx test related tasks -----------
-
-        /*
-        protected void removeDuplicates(List<TKey> destroyedKeys)
-        {
-          List<TKey> myStringList = new List<TKey>();
-          foreach (TKey s in destroyedKeys)
-          {
-            if (!myStringList.Contains(s))
-            {
-              myStringList.Add(s);
-            }
-          }
-          destroyedKeys = myStringList;
-          //return myStringList;
-        }
-        protected TVal GetValue()
-        {
-            TVal tmpValue = default(TVal);
-            ResetKey("valueSizes");
-            int size = GetUIntValue("valueSizes");
-            StringBuilder builder = new StringBuilder();
-            Random random = new Random();
-            char ch;
-            for (int j = 0; j < size; j++)
-            {
-              ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
-              builder.Append(ch);
-            }
-            ResetKey("objectType");
-            string objectType = GetStringValue(ObjectType);
-            ResetKey("elementSize");
-            int elementSize = GetUIntValue("elementSize");
-            ResetKey("versionNum");
-            int versionnum = GetUIntValue("versionNum"); //random.Next(2) + 1;// (counter++ % 2) + 1;
-            if (typeof(TVal) == typeof(string))
-            {
-              tmpValue = (TVal)(object)builder.ToString();
-            }
-            else if (typeof(TVal) == typeof(byte[]))
-            {
-              tmpValue = (TVal)(object)(Encoding.ASCII.GetBytes(builder.ToString()));
-            }
-            else if (objectType.Equals("PdxVersioned") && versionnum == 1)
-            {
-              FwkInfo("rjk ---11222 {0}", elementSize);
-              m_pdxVesionOneAsm = Assembly.LoadFrom(m_sharePath + "/PdxVersion1Lib.dll");
-              Type pt = m_pdxVesionOneAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-              FwkInfo("rjk ---11223");
-              tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, null);
-              FwkInfo("rjk ---11224 {0}", tmpValue);
-            }
-            else if (objectType.Equals("PdxVersioned") && versionnum == 2)
-            {
-              m_pdxVesionTwoAsm = Assembly.LoadFrom(m_sharePath + "/PdxVersion2Lib.dll");
-              Type pt = m_pdxVesionTwoAsm.GetType("PdxVersionTests.PdxVersioned", true, true);
-              tmpValue = (TVal)pt.InvokeMember("PdxVersioned", BindingFlags.CreateInstance, null, null, null);
-             }
-             FwkInfo("rjk: PdxVersioned {0}", versionnum);
-            return tmpValue;
-      
-        }
-           */
-        protected void verifyContainsKey(IRegion<TKey, TVal> m_region, TKey key, bool expected)
-        {
-            //bool containsKey = m_region.GetLocalView().ContainsKey(key);
-
-            bool containsKey = false;
-            if (isEmptyClient || m_istransaction)
-            {
-                containsKey = m_region.ContainsKey(key);
-            }
-            else
-            {
-                containsKey = m_region.GetLocalView().ContainsKey(key);
-            }
-            if (containsKey != expected)
-            {
-                throw new Exception("Expected ContainsKey() for " + key + " to be " + expected +
-                          " in " + m_region.FullPath + ", but it is " + containsKey);
-            }
-        }
-
-        protected void verifyContainsValueForKey(IRegion<TKey, TVal> m_region, TKey key, bool expected)
-        {
-
-            //bool containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-            bool containsValueForKey = false;
-            if (isEmptyClient || m_istransaction)
-                containsValueForKey = m_region.ContainsValueForKey(key);
-            else
-                containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-            Util.Log("Expected val is {0} and containsValueForKey is {1}", expected, containsValueForKey);
-            if (containsValueForKey != expected)
-            {
-                throw new Exception("Expected ContainsValueForKey() for " + key + " to be " + expected +
-                          " in " + m_region.FullPath + ", but it is " + containsValueForKey);
-            }
-
-        }
-        protected void verifySize(IRegion<TKey, TVal> m_region, int expectedSize)
-        {
-            int size = 0;
-            if (isEmptyClient || m_istransaction)
-                size = m_region.Count;
-            else
-                size = m_region.GetLocalView().Count;
-            if (size != expectedSize)
-            {
-                if (size < 1000)
-                {
-                    StringBuilder sb = new StringBuilder();
-                    sb.Append("region has wrong size (").Append(size)
-                      .Append(").  Dump of region follows:")
-                      .Append("\n");
-                    ICollection<RegionEntry<TKey, TVal>> regionentry = m_region.GetEntries(false);
-                    foreach (RegionEntry<TKey, TVal> kvp in regionentry)
-                    {
-                        TKey key = kvp.Key;
-                        TVal Value = kvp.Value;
-                        sb.Append(key).Append(") -> ").Append(Value)
-                           .Append("\n");
-                    }
-                    FwkInfo(sb.ToString());
-                }
-                throw new Exception("Expected size of " + m_region.FullPath + " to be " +
-                   expectedSize + ", but it is " + size);
-            }
-        }
-
-        public void DoWaitForSilenceListenerComplete()
-        {
-            int desiredSilenceSec = 30;
-            int sleepMS = 2000;
-            FwkInfo("Waiting for a period of silence for " + desiredSilenceSec + " seconds...");
-            long desiredSilenceMS = desiredSilenceSec * 1000;
-            long silenceStartTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-            long currentTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-            long lastEventTime = (long)Util.BBGet("ListenerBB", "lastEventTime");
-
-            while (currentTime - silenceStartTime < desiredSilenceMS)
-            {
-                try
-                {
-                    Thread.Sleep(sleepMS);
-                }
-                catch (Exception e)
-                {
-                    FwkException("PerfTest::waitForSilence() Caught exception:" + e.Message);
-                }
-                lastEventTime = (long)Util.BBGet("ListenerBB", "lastEventTime");
-                if (lastEventTime > silenceStartTime)
-                {
-                    // restart the wait
-                    silenceStartTime = lastEventTime;
-                }
-                currentTime = DateTime.Now.Ticks / TimeSpan.TicksPerMillisecond;
-            }
-            long duration = currentTime - silenceStartTime;
-            FwkInfo("Done waiting, clients have been silent for " + duration + " ms");
-
-        }
-        public void DoRandomEntryOperation()
-        {
-            FwkInfo("In DoRandomEntryOperation");
-            try
-            {
-                IRegion<TKey, TVal> region = GetRegion();
-                int timedInterval = GetTimeValue("timedInterval") * 1000;
-                if (timedInterval <= 0)
-                {
-                    timedInterval = 5000;
-                }
-                int maxTime = 10 * timedInterval;
-
-                // Loop over key set sizes
-                ResetKey("distinctKeys");
-                int numKeys = GetUIntValue("distinctKeys");
-                bool isdone = false;
-                Util.BBSet("RoundPositionBB", "done", false);
-                string clntid = null;
-                int roundPosition = 0;
-                if (isSerialExecution)
-                {
-                    Util.BBSet("RoundPositionBB", "roundPosition", 1);
-                    roundPosition = (int)Util.BBGet("RoundPositionBB", "roundPosition");
-                    clntid = String.Format("Client.{0}", roundPosition);
-
-                }
-                else
-                {
-                    clntid = Util.ClientId;
-                }
-                int numClients = GetUIntValue("clientCount");
-                string dummyClntid = null;
-                ResetKey("numThreads");
-                int numThreads = GetUIntValue("numThreads");
-                while (true)
-                {
-                  if (roundPosition > numClients)
-                  break;
-                  try
-                  {
-                    if (clntid.Equals(Util.ClientId))
-                    {
-                      PdxEntryTask<TKey, TVal> entrytask = new PdxEntryTask<TKey, TVal>(region, numKeys, regionSnapshot,
-                                destroyedKeys, isSerialExecution, objectType, versionnum);
-                      if (isSerialExecution)
-                              {
-                                  RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-                                  DoWaitForSilenceListenerComplete();
-                                  Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-                                  Util.BBSet("DestroyedKeys", "destroyedKeys", destroyedKeys);
-
-                                  roundPosition = Util.BBIncrement("RoundPositionBB", "roundPosition");
-                                  Util.BBSet("RoundPositionBB", "roundPosition", roundPosition);
-                                  Util.BBSet("RoundPositionBB", "done", true);
-                                  Util.BBSet("RoundPositionBB", "VerifyCnt", 0);
-                              }
-                              else
-                              {
-                                  RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-                                  break;
-                              }
-                              FwkInfo("Done PdxEntryTask operation");
-
-                       }
-                        else// if(!Util.ClientId.Equals(dummyClntid))
-                        {
-                            for (; ; )
-                            {
-                                isdone = (bool)Util.BBGet("RoundPositionBB", "done");
-                                if (isdone)
-                                    break;
-                            }
-                                if (isdone)
-                                {
-                                    //Thread.Sleep(35000);
-                                    try
-                                    {
-                                        verifyFromSnapshot();
-                                        Util.BBSet("RoundPositionBB", "done", false);
-                                        Util.BBIncrement("RoundPositionBB", "VerifyCnt");
-                                    }
-                                    catch (Exception ex)
-                                    {
-                                        Util.BBSet("RoundPositionBB", "done", false);
-                                        Util.BBIncrement("RoundPositionBB", "VerifyCnt");
-                                        Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-                                        FwkException("In DoRandomEntryOperation() caught excption {0}.", ex.Message);                                  
-                                    }
-
-                                }
-                                Thread.Sleep(100);
-                                FwkInfo("Done Verification and verifyCount = {0}",(int)Util.BBGet("RoundPositionBB", "VerifyCnt"));
-                            
-                        }
-                        if (isSerialExecution)
-                        {
-                            int verifyCnt = (int)Util.BBGet("RoundPositionBB", "VerifyCnt");
-                            FwkInfo("DoRandomOperation: verifyCnt {0}, numclient {1}", verifyCnt, numClients);
-                            while (verifyCnt < numClients - 1)
-                            {
-                                verifyCnt = (int)Util.BBGet("RoundPositionBB", "VerifyCnt");
-                                Thread.Sleep(100);
-                            }
-                            roundPosition = (int)Util.BBGet("RoundPositionBB", "roundPosition");
-                            clntid = String.Format("Client.{0}", roundPosition);
-                            dummyClntid = String.Format("Client.{0}", (roundPosition - 1));
-                        }
-                            Thread.Sleep(3000);
-                        
-                    }
-                    catch (ClientTimeoutException)
-                    {
-                        Util.BBSet("RoundPositionBB", "done", true);
-                        Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-                        FwkException("In DoRandomEntryOperation()  Timed run timed out.");
-                    }
-                    catch (Exception ex)
-                    {
-                        Util.BBSet("RoundPositionBB", "done", true);
-                        Util.BBSet("RoundPositionBB", "roundPosition", numClients + 1);
-                        FwkException("In DoRandomEntryOperation() caught excption {0}.", ex.Message);
-                    }
-                    Thread.Sleep(3000);
-
-                }
-            }
-            catch (Exception ex)
-            {
-                FwkException("last DoRandomEntryOperation() Caught Exception: {0}", ex.Message);
-            }
-            FwkInfo("DoRandomEntryOperation() complete.");
-        }
-        public void verifyFromSnapshot()
-        {
-            try
-            {
-                verifyFromSnapshotOnly();
-            }
-            catch (Exception e)
-            {
-                FwkException(e.Message);
-            }
-            //verifyInternalPRState();
-        }
-        public void verifyFromSnapshotOnly()
-        {
-            IRegion<TKey, TVal> aRegion = GetRegion();
-            if (isEmptyClient)
-            {
-                verifyServerKeysFromSnapshot();
-                return;
-            }
-            StringBuilder aStr = new StringBuilder();
-            regionSnapshot = (Dictionary<TKey, TVal>)Util.BBGet("RegionSnapshot", "regionSnapshot");
-            int snapshotSize = regionSnapshot.Count;
-            int regionSize = 0;
-            if (isEmptyClient || m_istransaction)
-                regionSize = aRegion.Count;
-            else
-                regionSize = aRegion.GetLocalView().Count;
-            //int regionSize = aRegion.GetLocalView().Count;
-            FwkInfo("Verifying from snapshot containing " + snapshotSize + " entries...");
-            if (snapshotSize != regionSize)
-            {
-                FwkException("Expected region " + aRegion.FullPath + " to be size " + snapshotSize +
-                     ", but it is " + regionSize.ToString() + "\n");
-            }
-            foreach (KeyValuePair<TKey, TVal> kvp in regionSnapshot)
-            {
-                TKey key = kvp.Key;
-                TVal expectedValue = kvp.Value;
-                try
-                {
-                    verifyContainsKey(aRegion, key, true);
-                }
-                catch (Exception e)
-                {
-                    aStr.Append(e.Message + "\n");
-                    //         anyFailures = true;
-                }
-                bool containsValueForKey = aRegion.GetLocalView().ContainsValueForKey(key);
-                try
-                {
-                    verifyContainsValueForKey(aRegion, key, !(EqualityComparer<TVal>.Default.Equals(expectedValue, default(TVal))));
-                }
-                catch (Exception e)
-                {
-                    FwkException(e.Message + "\n");
-                }
-
-                // do a get on the partitioned region if a loader won't get invoked; test its value
-                if (containsValueForKey)
-                {
-                    // loader won't be invoked if we have a value for this key (whether or not a loader
-                    // is installed), or if we don't have a loader at all
-                    try
-                    {
-                        TVal actualValue = aRegion[key];
-                        if (!actualValue.Equals(expectedValue))
-                        {
-                            FwkException("verifyFromSnapshotOnly: expected value {0} is not same as actual value {1} for key {3}",
-                              expectedValue, actualValue, key);
-                        }
-                       
-                    }
-                    catch (Apache.Geode.Client.KeyNotFoundException)
-                    {
-                    }
-                    catch (Exception e)
-                    {
-                        aStr.Append(e.Message + "\n");
-                    }
-                }
-            }
-            if (isSerialExecution)
-            {
-                // check that destroyedKeys are not in the region
-                destroyedKeys = (List<TKey>)Util.BBGet("DestroyedKeys", "destroyedKeys");
-                for (int i = 0; i < destroyedKeys.Count; i++)
-                {
-                    TKey key = destroyedKeys[i];
-                    try
-                    {
-                        verifyContainsKey(aRegion, key, false);
-                    }
-                    catch (Exception e)
-                    {
-                        aStr.Append(e.Message + "\n");
-                    }
-                }
-            }
-            try
-            {
-                verifyServerKeysFromSnapshot();
-            }
-            catch (Exception e)
-            {
-                aStr.Append(e.Message + "\n");
-            }
-
-            if (aStr.Length > 0)
-            {
-                // shutdownHook will cause all members to dump partitioned region info
-                throw new Exception(aStr.ToString());
-            }
-            FwkInfo("Done verifying from snapshot containing " + snapshotSize.ToString() + " entries...");
-        }
-        public void dumpDataOnBB()
-        {
-            IRegion<TKey, TVal> aRegion = GetRegion();
-            ICollection<TKey> serverkeys = aRegion.Keys;
-            regionSnapshot = new Dictionary<TKey, TVal>();
-            foreach (TKey key in serverkeys)
-            {
-                TVal value = default(TVal); ;
-                try
-                {
-                    value = aRegion[key];
-                }
-                catch (Apache.Geode.Client.KeyNotFoundException)
-                {
-                    value = default(TVal);
-                }
-                regionSnapshot[key] = value;
-            }
-            Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-        }
-        public void verifyServerKeysFromSnapshot()
-        {
-            IRegion<TKey, TVal> aRegion = GetRegion();
-            StringBuilder aStr = new StringBuilder();
-            regionSnapshot = (Dictionary<TKey, TVal>)Util.BBGet("RegionSnapshot", "regionSnapshot");
-            destroyedKeys = (List<TKey>)Util.BBGet("DestroyedKeys", "destroyedKeys");
-            ICollection<TKey> serverKeys = new System.Collections.ObjectModel.Collection<TKey>();
-            foreach (TKey key in aRegion.Keys)
-                serverKeys.Add(key);
-
-            int snapshotSize = regionSnapshot.Count;
-            int numServerKeys = serverKeys.Count;
-            //int numServerKeys = aRegion.Count;
-            FwkInfo("Verifying server keys from snapshot containing " + snapshotSize.ToString() + " entries...");
-            if (snapshotSize != numServerKeys)
-            {
-                aStr.Append("Expected number of keys on server to be " + snapshotSize.ToString() + ", but it is " + numServerKeys.ToString() + "\n");
-            }
-            foreach (KeyValuePair<TKey, TVal> kvp in regionSnapshot)
-            { // iterating the expected keys
-                TKey key = kvp.Key;
-                TVal expectedValue = (TVal)(Object)kvp.Value;
-                if (!serverKeys.Contains(key))
-                {
-                    aStr.Append("Expected key " + key + " to be in server keys set, but it is missing\n");
-                }
-                else
-                {
-                    // only do a get if we will not invoke the silence listener on a get
-                    if ((!isThinClient && !isEmptyClient) ||
-                        (isThinClient && aRegion.GetLocalView().ContainsKey(key)))
-                    {
-                        try
-                        {
-                            TVal valueOnServer = (TVal)(Object)aRegion[key];
-
-                            //if (!EqualityComparer<TVal>.Default.Equals(valueOnServer, default(TVal)))
-                            //{
-                            if (!valueOnServer.Equals(expectedValue))
-                            {
-                                FwkException("verifyServerKeysFromSnapshot: expected value {0} is not same as actual value {1} for key {2}",
-                                  expectedValue, valueOnServer, key);
-                            }
-                            FwkInfo("verifyServerKeysFromSnapshot: expected value {0} is same as actual value {1} for key {2}",
-                                expectedValue, valueOnServer, key);
-                            //}
-                        }
-                        catch (Apache.Geode.Client.KeyNotFoundException)
-                        {
-                        }
-                        catch (EntryNotFoundException)
-                        {
-                        }
-                        catch (Exception e)
-                        {
-                            aStr.Append(e.Message + "\n");
-                        }
-                    }
-                }
-            }
-
-            // check that destroyedKeys are not in the server keys
-            if (isSerialExecution)
-            {
-                destroyedKeys = (List<TKey>)Util.BBGet("DestroyedKeys", "destroyedKeys");
-                for (int i = 0; i < destroyedKeys.Count; i++)
-                {
-                    TKey key = destroyedKeys[i];
-                    if (serverKeys.Contains(key))
-                    {
-                        aStr.Append("Destroyed key " + key + " was returned as a server key\n");
-                    }
-                }
-
-
-                foreach (TKey key in regionSnapshot.Keys)
-                {
-                    FwkInfo("IsReadOnly {0}", serverKeys.IsReadOnly);
-                    FwkInfo("serverKeys  key {0}", key);
-                    serverKeys.Remove(key);
-                }
-                if (serverKeys.Count != 0)
-                {
-                    foreach (TKey key in serverKeys)
-                    {
-                        aStr.Append("Found the following unexpected keys in server keys: " +
-                                    ": " + key + "\n");
-                    }
-                }
-            }
-            if (aStr.Length > 0)
-            {
-                // shutdownHook will cause all members to dump partitioned region info
-                throw new Exception(aStr.ToString());
-            }
-            FwkInfo("Done verifying server keys from snapshot containing " + snapshotSize.ToString() + " entries...");
-        }
-        
-        public void DoPopulateRegion()
-        {
-            FwkInfo("In DoPopulateRegion()");
-            try
-            {
-                IRegion<TKey, TVal> region = GetRegion();
-                ResetKey("distinctKeys");
-                int numKeys = GetUIntValue("distinctKeys");
-                ResetKey("versionNum");
-                versionnum = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("versionNum");
-                PdxEntryTask<TKey, TVal> addtask = new PdxEntryTask<TKey, TVal>(region, numKeys,
-                    regionSnapshot, destroyedKeys, isSerialExecution, objectType, versionnum);
-                FwkInfo("Populating region for {0} keys.", numKeys);
-                RunTask(addtask, 1, numKeys, -1, -1, null);
-                Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-                Util.BBSet("DestroyedKeys", "destroyedKeys", destroyedKeys);
-            }
-            catch (Exception ex)
-            {
-                FwkException("DoPopulateRegion() Caught Exception: {0}", ex);
-            }
-            FwkInfo("DoPopulateRegion() complete.");
-        }
-
-        public void DoPuts()
-        {
-            FwkInfo("In DoPuts()");
-            try
-            {
-                IRegion<TKey, TVal> region = GetRegion();
-                int timedInterval = GetTimeValue("timedInterval") * 1000;
-                if (timedInterval <= 0)
-                {
-                    timedInterval = 5000;
-                }
-                int maxTime = 10 * timedInterval;
-
-                // Loop over key set sizes
-                ResetKey("versionNum");
-                versionnum = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("versionNum");
-                ResetKey(DistinctKeys);
-                int numKeys;
-                while ((numKeys = GetUIntValue(DistinctKeys)) > 0)
-                { // keys loop
-                    // Loop over value sizes
-                    ResetKey(ValueSizes);
-                    int valSize;
-                    while ((valSize = GetUIntValue(ValueSizes)) > 0)
-                    { // value loop
-                        // Loop over threads
-                        ResetKey(NumThreads);
-                        int numThreads;
-                        while ((numThreads = GetUIntValue(NumThreads)) > 0)
-                        {
-                            try
-                            {
-                              PdxEntryTask<TKey, TVal> puts = new PdxEntryTask<TKey, TVal>(region, numKeys,
-                                    regionSnapshot, destroyedKeys, isSerialExecution, objectType, versionnum);
-
-                                FwkInfo("Running warmup task for {0} iterations.", numKeys);
-                                RunTask(puts, 1, numKeys, -1, -1, null);
-                                // Running the warmup task
-                                Thread.Sleep(3000);
-                                // And we do the real work now
-                                FwkInfo("Running timed task for {0} secs and {1} threads; numKeys[{2}]",
-                                  timedInterval / 1000, numThreads, numKeys);
-                                //SetTaskRunInfo(label, "Puts", m_maxKeys, numClients,
-                                //  valSize, numThreads);
-                                RunTask(puts, numThreads, -1, timedInterval, maxTime, null);
-                                Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-                                Util.BBSet("DestroyedKeys", "destroyedKeys", destroyedKeys);
-                                //AddTaskRunRecord(puts.Iterations, puts.ElapsedTime);
-
-                            }
-                            catch (ClientTimeoutException)
-                            {
-                                FwkException("In DoPuts()  Timed run timed out.");
-                            }
-                            Thread.Sleep(3000); // Put a marker of inactivity in the stats
-                        }
-                        Thread.Sleep(3000); // Put a marker of inactivity in the stats
-                    } // value loop
-                    Thread.Sleep(3000); // Put a marker of inactivity in the stats
-                } // keys loop
-            }
-            catch (Exception ex)
-            {
-                FwkException("DoPuts() Caught Exception: {0}", ex);
-            }
-            Thread.Sleep(3000); // Put a marker of inactivity in the stats
-            FwkInfo("DoPuts() complete.");
-        }
-        public void DoGets()
-        {
-            FwkInfo("In DoGets()");
-            try
-            {
-                IRegion<TKey, TVal> region = GetRegion();
-                int numClients = GetUIntValue(ClientCount);
-                string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-                int timedInterval = GetTimeValue(TimedInterval) * 1000;
-                if (timedInterval <= 0)
-                {
-                    timedInterval = 5000;
-                }
-                int maxTime = 10 * timedInterval;
-
-                ResetKey(DistinctKeys);
-                int numKeys = GetUIntValue(DistinctKeys);
-                ResetKey("versionNum");
-                versionnum = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("versionNum");
-                
-                int valSize = GetUIntValue(ValueSizes);
-                // Loop over threads
-                ResetKey(NumThreads);
-                int numThreads;
-                while ((numThreads = GetUIntValue(NumThreads)) > 0)
-                { // thread loop
-
-                    // And we do the real work now
-                    PdxEntryTask<TKey, TVal> gets = new PdxEntryTask<TKey, TVal>(region, numKeys,
-                        regionSnapshot, destroyedKeys, isSerialExecution, objectType, versionnum);
-                    FwkInfo("Running warmup task for {0} iterations.", numKeys);
-                    RunTask(gets, 1, numKeys, -1, -1, null);
-                    region.GetLocalView().InvalidateRegion();
-                    Thread.Sleep(3000);
-                    FwkInfo("Running timed task for {0} secs and {1} threads.",
-                      timedInterval / 1000, numThreads);
-                    //SetTaskRunInfo(label, "Gets", m_maxKeys, numClients, valSize, numThreads);
-                    try
-                    {
-                        RunTask(gets, numThreads, -1, timedInterval, maxTime, null);
-                    }
-                    catch (ClientTimeoutException)
-                    {
-                        FwkException("In DoGets()  Timed run timed out.");
-                    }
-                    //AddTaskRunRecord(gets.Iterations, gets.ElapsedTime);
-                    // real work complete for this pass thru the loop
-                    Util.BBSet("RegionSnapshot", "regionSnapshot", regionSnapshot);
-                    Util.BBSet("DestroyedKeys", "destroyedKeys", destroyedKeys);
-                    Thread.Sleep(3000);
-                } // thread loop
-            }
-            catch (Exception ex)
-            {
-                FwkException("DoGets() Caught Exception: {0}", ex);
-            }
-            Thread.Sleep(3000);
-            FwkInfo("DoGets() complete.");
-        }
-
-        void doAccessPdxInstanceAndVerify()
-        {
-            CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterPdxType(PdxType.CreateDeserializable);
-            FwkInfo("In doAccessPdxInstanceAndVerify");
-            IRegion<TKey, TVal> region0 = GetRegion();
-            PdxType dPdxType = new PdxType();
-            ResetKey(DistinctKeys);
-            int numKeys = GetUIntValue(DistinctKeys);
-            int size = region0.Keys.Count;
-            TKey[] keys = (TKey[])region0.Keys;
-            TKey key = default(TKey);
-            try
-            {
-                if(size != numKeys){
-                    FwkException("doAccessPdxInstanceAndVerify() number of entries {0} on server is not same as expected {1}", size, numKeys);
-                }
-                for (int index = 0; index < numKeys; index++)
-                {
-                    key = keys[index];
-                    bool containsValueForKey = false;
-                    if (isEmptyClient || m_istransaction)
-                        containsValueForKey = region0.ContainsValueForKey(key);
-                    else
-                        containsValueForKey = region0.GetLocalView().ContainsValueForKey(key);
-                    IPdxInstance ret = (IPdxInstance)region0[key];
-                    string retStr = (string)ret.GetField("m_string");
-                    PdxType.GenericValCompare(dPdxType.PString, retStr);
-
-                    PdxType.GenericValCompare((char)ret.GetField("m_char"), dPdxType.Char);
-
-                    byte[][] baa = (byte[][])ret.GetField("m_byteByteArray");
-                    PdxType.compareByteByteArray(baa, dPdxType.ByteByteArray);
-
-                    PdxType.GenericCompare((char[])ret.GetField("m_charArray"), dPdxType.CharArray);
-
-                    bool bl = (bool)ret.GetField("m_bool");
-                    PdxType.GenericValCompare(bl, dPdxType.Bool);
-                    PdxType.GenericCompare((bool[])ret.GetField("m_boolArray"), dPdxType.BoolArray);
-
-                    PdxType.GenericValCompare((sbyte)ret.GetField("m_byte"), dPdxType.Byte);
-                    PdxType.GenericCompare((byte[])ret.GetField("m_byteArray"), dPdxType.ByteArray);
-
-
-                    List<object> tmpl = (List<object>)ret.GetField("m_arraylist");
-
-                    PdxType.compareCompareCollection(tmpl, dPdxType.Arraylist);
-
-                    IDictionary<object, object> tmpM = (IDictionary<object, object>)ret.GetField("m_map");
-                    if (tmpM.Count != dPdxType.Map.Count)
-                        throw new IllegalStateException("Not got expected value for type: " + dPdxType.Map.GetType().ToString());
-
-                    Hashtable tmpH = (Hashtable)ret.GetField("m_hashtable");
-
-                    if (tmpH.Count != dPdxType.Hashtable.Count)
-                        throw new IllegalStateException("Not got expected value for type: " + dPdxType.Hashtable.GetType().ToString());
-
-                    ArrayList arrAl = (ArrayList)ret.GetField("m_vector");
-
-                    if (arrAl.Count != dPdxType.Vector.Count)
-                        throw new IllegalStateException("Not got expected value for type: " + dPdxType.Vector.GetType().ToString());
-
-                    CacheableHashSet rmpChs = (CacheableHashSet)ret.GetField("m_chs");
-
-                    if (rmpChs.Count != dPdxType.Chs.Count)
-                        throw new IllegalStateException("Not got expected value for type: " + dPdxType.Chs.GetType().ToString());
-
-                    CacheableLinkedHashSet rmpClhs = (CacheableLinkedHashSet)ret.GetField("m_clhs");
-
-                    if (rmpClhs.Count != dPdxType.Clhs.Count)
-                        throw new IllegalStateException("Not got expected value for type: " + dPdxType.Clhs.GetType().ToString());
-
-
-                    PdxType.GenericValCompare((string)ret.GetField("m_string"), dPdxType.String);
-
-                    PdxType.compareData((DateTime)ret.GetField("m_dateTime"), dPdxType.DateTime);
-
-                    PdxType.GenericValCompare((double)ret.GetField("m_double"), dPdxType.Double);
-
-                    PdxType.GenericCompare((long[])ret.GetField("m_longArray"), dPdxType.LongArray);
-                    PdxType.GenericCompare((Int16[])ret.GetField("m_int16Array"), dPdxType.Int16Array);
-                    PdxType.GenericValCompare((sbyte)ret.GetField("m_sbyte"), dPdxType.Sbyte);
-                    PdxType.GenericCompare((byte[])ret.GetField("m_sbyteArray"), dPdxType.SbyteArray);
-                    PdxType.GenericCompare((string[])ret.GetField("m_stringArray"), dPdxType.StringArray);
-                    PdxType.GenericValCompare((Int16)ret.GetField("m_uint16"), dPdxType.Uint16);
-                    PdxType.GenericValCompare((int)ret.GetField("m_uint32"), dPdxType.Uint32);
-                    PdxType.GenericValCompare((long)ret.GetField("m_ulong"), dPdxType.Ulong);
-                    PdxType.GenericCompare((int[])ret.GetField("m_uint32Array"), dPdxType.Uint32Array);
-
-                    PdxType.GenericCompare((double[])ret.GetField("m_doubleArray"), dPdxType.DoubleArray);
-                    PdxType.GenericValCompare((float)ret.GetField("m_float"), dPdxType.Float);
-                    PdxType.GenericCompare((float[])ret.GetField("m_floatArray"), dPdxType.FloatArray);
-                    PdxType.GenericValCompare((Int16)ret.GetField("m_int16"), dPdxType.Int16);
-                    PdxType.GenericValCompare((Int32)ret.GetField("m_int32"), dPdxType.Int32);
-                    PdxType.GenericValCompare((long)ret.GetField("m_long"), dPdxType.Long);
-                    PdxType.GenericCompare((int[])ret.GetField("m_int32Array"), dPdxType.Int32Array);
-
-                    PdxType.GenericCompare((long[])ret.GetField("m_ulongArray"), dPdxType.UlongArray);
-                    PdxType.GenericCompare((Int16[])ret.GetField("m_uint16Array"), dPdxType.Uint16Array);
-
-                    byte[] retbA = (byte[])ret.GetField("m_byte252");
-                    if (retbA.Length != 252)
-                        throw new Exception("Array len 252 not found");
-
-                    retbA = (byte[])ret.GetField("m_byte253");
-                    if (retbA.Length != 253)
-                        throw new Exception("Array len 253 not found");
-
-                    retbA = (byte[])ret.GetField("m_byte65535");
-                    if (retbA.Length != 65535)
-                        throw new Exception("Array len 65535 not found");
-
-                    retbA = (byte[])ret.GetField("m_byte65536");
-                    if (retbA.Length != 65536)
-                        throw new Exception("Array len 65536 not found");
-
-                    pdxEnumTest ev = (pdxEnumTest)ret.GetField("m_pdxEnum");
-                    if (ev != dPdxType.PdxEnum)
-                        throw new Exception("Pdx enum is not equal");
-
-                    IPdxInstance[] addreaaPdxI = (IPdxInstance[])ret.GetField("m_address");
-                    if (addreaaPdxI.Length != dPdxType.AddressArray.Length)
-                        throw new Exception("Address array not mateched ");
-                    
-
-                    List<object> objArr = (List<object>)ret.GetField("m_objectArray");
-                    
-                    if (objArr.Count != dPdxType.ObjectArray.Count)
-                       throw new Exception("Object array not mateched ");
-                    
-
-                }
-            }
-            catch (Exception ex)
-            {
-                FwkException("doAccessPdxInstanceAndVerify() Caught Exception: {0}", ex);
-            }
-        }
-        public void exceptionThrow(IPdxInstance newpdxins, IPdxInstance pdxins)
-        {
-            if (pdxins.Equals(newpdxins))
-            {
-                throw new Exception("PdxInstance should not be equal");
-            }
-        }
-        public void doModifyPdxInstance()
-        {
-            FwkInfo("In doModifyPdxInstance");
-            IRegion<TKey, TVal> region0 = GetRegion();
-            int size;
-            if (isEmptyClient || m_istransaction)
-            {
-                size = region0.Keys.Count;
-            }
-            else
-            {
-                size = region0.Count;
-            }
-            ResetKey(DistinctKeys);
-            int numKeys = GetUIntValue(DistinctKeys);
-            //int size = region0.Count;
-            TKey[] keys = (TKey[])region0.Keys;
-            TKey key = default(TKey);
-            try
-            {
-                if(size != numKeys){
-                    FwkException("doModifyPdxInstance() number of entries {0} on server is not same as expected {1}",size,numKeys);
-                }
-                for (int index = 0; index < numKeys; index++)
-                {
-                    
-                    key = keys[index];
-                    IPdxInstance newpdxins;
-                    IPdxInstance pdxins = (IPdxInstance)region0[key];
-
-                    int oldVal = (int)pdxins.GetField("m_int32");
-                    IWritablePdxInstance iwpi = pdxins.CreateWriter();
-                    StringBuilder builder = new StringBuilder();
-                    Random random = new Random();
-                    char ch;
-                    for (int j = 0; j < 10; j++)
-                    {
-                        ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
-                        builder.Append(ch);
-                    }
-                    string changeStr = builder.ToString();
-                    //string changeStr = "change the string";
-                    iwpi.SetField("m_int32", oldVal + 1);
-                    iwpi.SetField("m_string", changeStr);
-                    region0[key] =(TVal)(object)iwpi;
-
-                    newpdxins = (IPdxInstance)region0[key];
-
-                    int newVal = (int)newpdxins.GetField("m_int32");
-                    if ((oldVal + 1) != newVal)
-                    {
-                        throw new Exception("PdxInstance field m_int32 of PdxType not get modified and " +
-                            "the previous value was " + oldVal + " and new value is " + newVal);
-                    }
-
-                    string cStr = (string)newpdxins.GetField("m_string");
-                    if (!cStr.Equals(changeStr))
-                    {
-                        throw new Exception("PdxInstance field m_string of PdxType not get modified and " +
-                            "the previous value was " + changeStr + " and new value is " + cStr);
-                    }
-
-                    List<object> arr = (List<object>)newpdxins.GetField("m_arraylist");
-                    exceptionThrow(newpdxins, pdxins);
-
-                    
-                    //int num = random.Next(0, 26); // Zero to 25
-                    //char newChar = (char)('a' + num);
-                    /*
-                    char oldChar = (char)pdxins.GetField("m_char");
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_char", 'D');
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    char newChar = (char)newpdxins.GetField("m_char");
-                    if (!(newChar.Equals('D')))
-                    {
-                        throw new Exception("PdxInstance field m_char of PdxType not get modified and " +
-                            "the previous value was " + oldChar + " and new value is " + newChar);
-                    }
-                    expcetionThrow(newpdxins, pdxins);
-                    */
-                    bool beforeValue = (bool)pdxins.GetField("m_bool");
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_bool", false);
-                    region0[key] = (TVal)(object)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    bool updateValue = (bool)newpdxins.GetField("m_bool");
-                    if(updateValue)
-                    {
-                        throw new Exception("PdxInstance field m_bool is not equal");
-                    }
-                    exceptionThrow(newpdxins, pdxins);
-                    /*
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_byte", (sbyte)0x75);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((sbyte)newpdxins.GetField("m_byte"), (sbyte)0x75, "sbyte is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_sbyte", (sbyte)0x57);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((sbyte)newpdxins.GetField("m_sbyte"), (sbyte)0x57, "sbyte is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_int16", (short)0x5678);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((Int16)newpdxins.GetField("m_int16"), (short)0x5678, "int16 is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_long", (long)0x56787878);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((long)newpdxins.GetField("m_long"), (long)0x56787878, "long is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_float", 18389.34f);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((float)newpdxins.GetField("m_float"), 18389.34f, "float is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_float", 18389.34f);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((float)newpdxins.GetField("m_float"), 18389.34f, "float is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_double", 18389.34d);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((double)newpdxins.GetField("m_double"), 18389.34d, "double is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_boolArray", new bool[] { true, false, true, false, true, true, false, true });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((bool[])newpdxins.GetField("m_boolArray"), new bool[] { true, false, true, false, true, true, false, true }, "bool array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_byteArray", new byte[] { 0x34, 0x64, 0x34, 0x64 });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((byte[])newpdxins.GetField("m_byteArray"), new byte[] { 0x34, 0x64, 0x34, 0x64 }, "byte array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_charArray", new char[] { 'c', 'v', 'c', 'v' });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((char[])newpdxins.GetField("m_charArray"), new char[] { 'c', 'v', 'c', 'v' }, "char array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    long ticks = 634460644691580000L;
-                    DateTime tdt = new DateTime(ticks);
-                    iwpi.SetField("m_dateTime", tdt);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((DateTime)newpdxins.GetField("m_dateTime"), tdt, "datetime is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_int16Array", new short[] { 0x2332, 0x4545, 0x88, 0x898 });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((Int16[])newpdxins.GetField("m_int16Array"), new short[] { 0x2332, 0x4545, 0x88, 0x898 }, "short array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_int32Array", new int[] { 23, 676868, 34343 });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((Int32[])newpdxins.GetField("m_int32Array"), new int[] { 23, 676868, 34343 }, "int32 array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_longArray", new Int64[] { 3245435, 3425435 });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((long[])newpdxins.GetField("m_longArray"), new Int64[] { 3245435, 3425435 }, "long array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_floatArray", new float[] { 232.565f, 234323354.67f });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((float[])newpdxins.GetField("m_floatArray"), new float[] { 232.565f, 234323354.67f }, "float array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_doubleArray", new double[] { 23423432d, 43242354315d });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((double[])newpdxins.GetField("m_doubleArray"), new double[] { 23423432d, 43242354315d }, "double array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    byte[][] tmpbb = new byte[][]{new byte[] {0x23},
-                    new byte[]{0x34, 0x55},
-                    new byte[] {0x23},
-                    new byte[]{0x34, 0x55}
-                    };
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_byteByteArray", tmpbb);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    byte[][] retbb = (byte[][])newpdxins.GetField("m_byteByteArray");
-
-                    PdxType.compareByteByteArray(tmpbb, retbb);
-
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_stringArray", new string[] { "one", "two", "eeeee" });
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((string[])newpdxins.GetField("m_stringArray"), new string[] { "one", "two", "eeeee" }, "string array is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-
-                    List<object> tl = new List<object>();
-                    tl.Add(new PdxType());
-                    tl.Add(new byte[] { 0x34, 0x55 });
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_arraylist", tl);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual(((List<object>)newpdxins.GetField("m_arraylist")).Count, tl.Count, "list<object> is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    Dictionary<object, object> map = new Dictionary<object, object>();
-                    map.Add(1, new bool[] { true, false, true, false, true, true, false, true });
-                    map.Add(2, new string[] { "one", "two", "eeeee" });
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_map", map);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual(((Dictionary<object, object>)newpdxins.GetField("m_map")).Count, map.Count, "map is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    Hashtable hashtable = new Hashtable();
-                    hashtable.Add(1, new string[] { "one", "two", "eeeee" });
-                    hashtable.Add(2, new int[] { 23, 676868, 34343 });
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_hashtable", hashtable);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual(((Hashtable)newpdxins.GetField("m_hashtable")).Count, hashtable.Count, "hashtable is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_pdxEnum", pdxEnumTest.pdx1);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual(((pdxEnumTest)newpdxins.GetField("m_pdxEnum")), pdxEnumTest.pdx1, "pdx enum is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    ArrayList vector = new ArrayList();
-                    vector.Add(1);
-                    vector.Add(2);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_vector", vector);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual(((ArrayList)newpdxins.GetField("m_vector")).Count, vector.Count, "vector is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    CacheableHashSet chm = CacheableHashSet.Create();
-                    chm.Add(1);
-                    chm.Add("jkfdkjdsfl");
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_chs", chm);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((CacheableHashSet)newpdxins.GetField("m_chs"), chm, "CacheableHashSet is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    CacheableLinkedHashSet clhs = CacheableLinkedHashSet.Create();
-                    clhs.Add(111);
-                    clhs.Add(111343);
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_clhs", clhs);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual((CacheableLinkedHashSet)newpdxins.GetField("m_clhs"), clhs, "CacheableLinkedHashSet is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    PdxTests.Address[] aa = new PdxTests.Address[2];
-                    for (int i = 0; i < aa.Length; i++)
-                    {
-                        aa[i] = new PdxTests.Address(i + 1, "street" + i.ToString(), "city" + i.ToString());
-                    }
-
-                    iwpi = pdxins.CreateWriter();
-
-                    iwpi.SetField("m_address", aa);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    IPdxInstance[] iaa = (IPdxInstance[])newpdxins.GetField("m_address");
-                    Assert.AreEqual(iaa.Length, aa.Length, "address array length should equal");
-                    expcetionThrow(newpdxins, pdxins);
-
-                    List<object> oa = new List<object>();
-                    oa.Add(new PdxTests.Address(1, "1", "12"));
-                    oa.Add(new PdxTests.Address(1, "1", "12"));
-
-                    iwpi = pdxins.CreateWriter();
-                    iwpi.SetField("m_objectArray", oa);
-                    region0[key] = (TVal)iwpi;
-                    newpdxins = (IPdxInstance)region0[key];
-                    Assert.AreEqual(((List<object>)newpdxins.GetField("m_objectArray")).Count, oa.Count, "Object arary is not equal");
-                    expcetionThrow(newpdxins, pdxins);
-                    */
-         
-                }
-            }
-            catch (Exception ex)
-            {
-                FwkException("doModifyPdxInstance() Caught Exception: {0}", ex);
-            }
-                
-        }
-
-        public void doVerifyAndModifyPdxInstance()
-        {
-            try
-            {
-                doAccessPdxInstanceAndVerify();
-                doModifyPdxInstance();
-            }
-            catch (Exception ex)
-            {
-                FwkException("doModifyPdxInstance() Caught Exception: {0}", ex);
-            }
-        }
-
-
-        // ------------------------------ end pdx ralated task ----------------
-        public void DoEntryOperations()
-        {
-            FwkInfo("CacheServer.DoEntryOperations() called.");
-
-            int opsSec = GetUIntValue(OpsSecond);
-            opsSec = (opsSec < 1) ? 0 : opsSec;
-
-            int entryCount = GetUIntValue(EntryCount);
-            entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-            int secondsToRun = GetTimeValue(WorkTime);
-            secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-            int valSize = GetUIntValue(ValueSizes);
-            int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-            valSize = ((valSize < minValSize) ? minValSize : valSize);
-
-            DateTime now = DateTime.Now;
-            DateTime end = now.AddSeconds(secondsToRun);
-
-            TKey key;
-            TVal value;
-            TVal tmpValue;
-            //TVal valBuf = (TVal)(object)Encoding.ASCII.GetBytes(new string('A', valSize));
-            byte[] valBuf = Encoding.ASCII.GetBytes(new string('A', valSize));
-            string opcode = null;
-
-            int creates = 0, puts = 0, gets = 0, dests = 0, invals = 0, query = 0, putAll = 0, getAll = 0;
-            IRegion<TKey, TVal> region = GetRegion();
-            if (region == null)
-            {
-                FwkSevere("CacheServer.DoEntryOperations(): No region to perform operations on.");
-                now = end; // Do not do the loop
-            }
-
-            FwkInfo("CacheServer.DoEntryOperations() will work for {0}secs " +
-              "using {1} byte values.", secondsToRun, valSize);
-
-            PaceMeter pm = new PaceMeter(opsSec);
-            string objectType = GetStringValue(ObjectType);
-            bool multiRegion = GetBoolValue("multiRegion");
-            while (now < end)
-            {
-                try
-                {
-                    opcode = GetStringValue(EntryOps);
-                    if (opcode == null || opcode.Length == 0)
-                    {
-                        opcode = "no-op";
-                    }
-                    if (multiRegion)
-                    {
-                        region = GetRegion();
-                        if (region == null)
-                        {
-                            FwkException("CacheServerTest::doEntryOperations(): No region to perform operation {0}", opcode);
-                        }
-                    }
-
-                    key = (TKey)(object)GetKey(entryCount);
-                    if (opcode == "add")
-                    {
-                        if (objectType != null && objectType.Length > 0)
-                        {
-                            tmpValue = (TVal)(object)GetUserObject(objectType);
-                        }
-                        else
-                        {
-                            tmpValue = (TVal)(object)valBuf;
-                        }
-                        try
-                        {
-                            region.Add(key, tmpValue);
-                            creates++;
-                        }
-                        catch (EntryExistsException ex)
-                        {
-                            FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                                 "ex-ception in add: {0}", ex.Message);
-                        }
-                    }
-                    else
-                    {
-                        if (opcode == "update")
-                        {
-                            if (objectType != null && objectType.Length > 0)
-                            {
-                                tmpValue = GetUserObject(objectType);
-                            }
-                            else
-                            {
-                                int keyVal = int.Parse(key.ToString());
-                                int val = BitConverter.ToInt32(valBuf, 0);
-                                val = (val == keyVal) ? keyVal + 1 : keyVal;  // alternate the value so that it can be validated later.
-                                BitConverter.GetBytes(val).CopyTo(valBuf, 0);
-                                BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-                                tmpValue = (TVal)(object)valBuf;
-                            }
-                            region[key] = tmpValue;
-                            puts++;
-                        }
-                        else if (opcode == "invalidate")
-                        {
-                            try
-                            {
-                                region.Invalidate(key);
-                                invals++;
-                            }
-                            catch (EntryNotFoundException ex)
-                            {
-                                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                                  "ex-ception in invalidate: {0}", ex.Message);
-                            }
-                        }
-                        else if (opcode == "destroy")
-                        {
-                            try
-                            {
-                                region.Remove(key);
-                                dests++;
-                            }
-                            catch (EntryNotFoundException ex)
-                            {
-                                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                                  "ex-ception in destroy: {0}", ex.Message);
-                            }
-                        }
-                        else if (opcode == "read")
-                        {
-                            try
-                            {
-                                value = (TVal)region[key];
-                                gets++;
-                            }
-                            catch (EntryNotFoundException ex)
-                            {
-                                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                                  "ex-ception in read: {0}", ex.Message);
-                            }
-                            catch (Apache.Geode.Client.KeyNotFoundException ex)
-                            {
-                                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                                  "ex-ception in read: {0}", ex.Message);
-                            }
-                        }
-                        else if (opcode == "read+localdestroy")
-                        {
-                            value = region[key];
-                            gets++;
-                            try
-                            {
-                                region.GetLocalView().Remove(key);
-                                dests++;
-                            }
-                            catch (EntryNotFoundException ex)
-                            {
-                                FwkInfo("CacheServer.DoEntryOperations() Caught non-fatal " +
-                                  "ex-ception in localDestroy: {0}", ex.Message);
-                            }
-                        }
-                        else if (opcode == "query")
-                        {
-                            RunQuery();
-                            query += 4;
-                        }
-                        else if (opcode == "putAll")
-                        {
-                            PutAllOps();
-                            putAll++;
-                        }
-                        else if (opcode == "getAll")
-                        {
-                            GetAllOps();
-                            getAll++;
-                        }
-                        else
-                        {
-                            FwkException("CacheServer.DoEntryOperations() Invalid operation " +
-                              "specified: {0}", opcode);
-                        }
-                    }
-                }
-                catch (Exception ex)
-                {
-                    FwkException("CacheServer.DoEntryOperations() Caught unexpected " +
-                      "exception during entry '{0}' operation: {1}.", opcode, ex);
-                }
-                pm.CheckPace();
-                now = DateTime.Now;
-            }
-            key = default(TKey);
-            value = default(TVal);
-
-            FwkInfo("CacheServer.DoEntryOperations() did {0} creates, {1} puts, " +
-              "{2} gets, {3} invalidates, {4} destroys, {5} querys, {6} putAll, {7} getAll.",
-              creates, puts, gets, invals, dests, query, putAll, getAll);
-        }
-
-        public void DoEntryOperationsForSecurity()
-        {
-            FwkInfo("CacheServer.DoEntryOperationsForSecurity() called.");
-            Util.RegisterTestCompleteDelegate(TestComplete);
-
-            int opsSec = GetUIntValue(OpsSecond);
-            opsSec = (opsSec < 1) ? 0 : opsSec;
-
-            int entryCount = GetUIntValue(EntryCount);
-            entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-            int secondsToRun = GetTimeValue(WorkTime);
-            secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-            int valSize = GetUIntValue(ValueSizes);
-            int minValSize = (int)(sizeof(int) + sizeof(long) + 4);
-            valSize = ((valSize < minValSize) ? minValSize : valSize);
-
-            DateTime now = DateTime.Now;
-            DateTime end = now.AddSeconds(secondsToRun);
-
-            TKey key;
-            TVal value;
-            TVal tmpValue;
-            byte[] valBuf = Encoding.ASCII.GetBytes(new string('A', valSize));
-
-            string opCode = null;
-
-            IRegion<TKey, TVal> region = GetRegion();
-            if (region == null)
-            {
-                FwkException("CacheServer.DoEntryOperationsForSecurity(): " +
-                  "No region to perform operations on.");
-            }
-
-            FwkInfo("CacheServer.DoEntryOperationsForSecurity() will work for {0}secs " +
-              "using {1} byte values.", secondsToRun, valSize);
-
-            int cnt = 0;
-            PaceMeter pm = new PaceMeter(opsSec);
-            string objectType = GetStringValue(ObjectType);
-            while (now < end)
-            {
-                int addOps = 1;
-                opCode = GetStringValue(EntryOps);
-                try
-                {
-                    UpdateOperationsMap(opCode, 1);
-                    if (opCode == null || opCode.Length == 0)
-                    {
-                        opCode = "no-op";
-                    }
-
-                    key = GetKey(entryCount);
-                    if (opCode == "create")
-                    {
-                        if (objectType != null && objectType.Length > 0)
-                        {
-                            tmpValue = GetUserObject(objectType);
-                        }
-                        else
-                        {
-                            tmpValue = (TVal)(object)valBuf;
-                        }
-                        region.Add(key, tmpValue);
-                    }
-                    else
-                    {
-                        if (opCode == "update")
-                        {
-                            if (objectType != null && objectType.Length > 0)
-                            {
-                                tmpValue = (TVal)(object)GetUserObject(objectType);
-                            }
-                            else
-                            {
-                                int keyVal = int.Parse(key.ToString());
-                                int val = BitConverter.ToInt32(valBuf, 0);
-                                val = (val == keyVal) ? keyVal + 1 : keyVal;  // alternate the value so that it can be validated later.
-                                BitConverter.GetBytes(val).CopyTo(valBuf, 0);
-                                BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-                                tmpValue = (TVal)(object)valBuf;
-                            }
-                            region[key] = tmpValue;
-                        }
-                        else if (opCode == "invalidate")
-                        {
-                            region.Invalidate(key);
-                        }
-                        else if (opCode == "destroy")
-                        {
-                            region.Remove(key);
-                        }
-                        else if (opCode == "get")
-                        {
-                            value = region[key];
-                        }
-                        else if (opCode == "read+localdestroy")
-                        {
-                            value = region[key];
-                            region.GetLocalView().Remove(key);
-                        }
-                        else if (opCode == "regNUnregInterest")
-                        {
-                            TKey[] keys = new TKey[] { key };
-                            region.GetSubscriptionService().RegisterKeys(keys);
-                            region.GetSubscriptionService().UnregisterKeys(keys);
-                        }
-                        else if (opCode == "query")
-                        {
-                            var qs = CheckQueryService();
-                            Query<object> qry = qs.NewQuery<object>("select distinct * from /Portfolios where FALSE");
-                            ISelectResults<object> result = qry.Execute(TimeSpan.FromSeconds(600));
-                        }
-                        else if (opCode == "cq")
-                        {
-                            string cqName = String.Format("cq-{0}-{1}", Util.ClientId, cnt++);
-                            var qs = CheckQueryService();
-                            CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-                            ICqListener<TKey, object> cqLstner = new MyCqListener<TKey, object>();
-                            cqFac.AddCqListener(cqLstner);
-                            CqAttributes<TKey, object> cqAttr = cqFac.Create();
-                            CqQuery<TKey, object> cq = qs.NewCq(cqName, "select * from /Portfolios where FALSE", cqAttr, false);
-                            cq.Execute();
-                            cq.Stop();
-                            cq.Execute();
-                            cq.Close();
-                        }
-                        else
-                        {
-                            FwkException("CacheServer.DoEntryOperationsForSecurity() " +
-                              "Invalid operation specified: {0}", opCode);
-                        }
-                    }
-                }
-                catch (NotAuthorizedException)
-                {
-                    //FwkInfo("Got expected NotAuthorizedException for operation {0}: {1}",
-                    //  opCode, ex.Message);
-                    UpdateExceptionsMap(opCode, 1);
-                }
-                catch (EntryExistsException)
-                {
-                    addOps = -1;
-                    UpdateOperationsMap(opCode, addOps);
-                }
-                catch (EntryNotFoundException)
-                {
-                    addOps = -1;
-                    UpdateOperationsMap(opCode, addOps);
-                }
-                catch (EntryDestroyedException)
-                {
-                    addOps = -1;
-                    UpdateOperationsMap(opCode, addOps);
-                }
-                catch (TimeoutException ex)
-                {
-                    FwkSevere("Caught unexpected timeout exception during entry {0} " +
-                      " operation: {1}; continuing with test.", opCode, ex.Message);
-                }
-                catch (Exception ex)
-                {
-                    FwkException("CacheServer.DoEntryOperationsForSecurity() Caught " +
-                      "unexpected exception during entry '{0}' operation: {1}.",
-                      opCode, ex);
-                }
-                pm.CheckPace();
-                now = DateTime.Now;
-            }
-            key = default(TKey);
-            value = default(TVal);
-        }
-
-        public void DoValidateEntryOperationsForSecurity()
-        {
-            bool isExpectedPass = GetBoolValue("isExpectedPass");
-            string opCode;
-            while ((opCode = GetStringValue(EntryOps)) != null)
-            {
-                int numOps = GetOpsFromMap(OperationsMap, opCode);
-                int notAuthzCount = GetOpsFromMap(ExceptionsMap, opCode);
-                if (isExpectedPass)
-                {
-                    if (numOps != 0 && notAuthzCount == 0)
-                    {
-                        FwkInfo("Task passed sucessfully for operation {0} with total " +
-                          "operations = {1}", opCode, numOps);
-                    }
-                    else
-                    {
-                        FwkException("{0} NotAuthorizedExceptions found for operation {1} " +
-                          "while expected 0", notAuthzCount, opCode);
-                    }
-                }
-                else
-                {
-                    if (numOps == notAuthzCount)
-                    {
-                        FwkInfo("Operation {0} passed sucessfully and got the expected " +
-                          "number of incorrect authorizations: {1}", opCode, numOps);
-                    }
-                    else
-                    {
-                        FwkException("For operation {0} expected number of " +
-                          "NotAuthorizedExceptions is {1} but found {2}", opCode,
-                          numOps, notAuthzCount);
-                    }
-                }
-            }
-        }
-
-        public static void TestComplete()
-        {
-            OperationsMap.Clear();
-            ExceptionsMap.Clear();
-        }
-
-        #endregion
-    }
-}
-
diff --git a/tests/cli/NewFwkLib/PerfTest/DupChecker.cs b/tests/cli/NewFwkLib/PerfTest/DupChecker.cs
deleted file mode 100644
index 49da89b..0000000
--- a/tests/cli/NewFwkLib/PerfTest/DupChecker.cs
+++ /dev/null
@@ -1,132 +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.
- */
-
-using System;
-using System.Collections.Generic;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-  //using Region = Apache.Geode.Client.IRegion<Object, Object>;
-
-
-  public class DupChecker<TKey, TVal> : CacheListenerAdapter<TKey, TVal>, IDisposable
-  {
-    /*
-  
-    Note:
-  
-    Currently, for failoverTestHAEventIDMap.xml, PerfTests.DoSerialPuts has a hardcoded
-    keycount of 1000 and values are put serially from 1 to 1000.
-  
-    */
-
-    #region Private members
-
-    int m_ops = 0;
-    Dictionary<TKey, TVal> m_map = new Dictionary<TKey, TVal>();
-    
-    #endregion
-
-    #region Private methods
-
-    private void check(EntryEvent<TKey, TVal> ev)
-    {
-      m_ops++;
-
-      TKey key = ev.Key;
-      TVal value = ev.NewValue;
-
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-
-      if (m_map.ContainsKey((TKey)key))
-      {
-        TVal old = m_map[(TKey)key];
-
-        currTest.FwkAssert(value.Equals(old) , "DupChecker: Duplicate detected. Existing value is {0}, New value is {1}",
-          old, value);
-      }
-
-      m_map[(TKey)key] = value;
-    }
-    
-    private void validate()
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-
-      currTest.FwkInfo("DupChecker: got {0} keys.", m_map.Count);
-
-      currTest.FwkAssert(m_map.Count == 1000, "DupChecker: Expected 1000 keys for the region, actual is {0}.", m_map.Count);
-
-      currTest.FwkInfo("DupChecker: got {0} ops.", m_ops);
-
-      currTest.FwkAssert(m_ops == 1000000, "DupChecker: Expected 1,000,000 events (1000 per key) for the region, actual is {0}.",
-        m_ops);
-
-      foreach (object item in m_map.Values)
-      {
-        int checkval = (int)item;
-        currTest.FwkAssert(checkval == 1000, "DupChecker: Expected 1000 as final value, actual is {0}.", checkval);
-      }
-    }
-
-    #endregion
-
-    #region ICacheListener Members
-
-    public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-      check(ev);
-    }
-
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      check(ev);
-    }
-
-    #endregion
-
-    protected virtual void Dispose(bool disposing)
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      currTest.FwkInfo("DupChecker: validating");
-      validate();
-    }
-
-    #region IDisposable Members
-
-    public void Dispose()
-    {
-      Dispose(true);
-      GC.SuppressFinalize(this);
-    }
-
-    #endregion
-
-    public DupChecker()
-    {
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      currTest.FwkInfo("DupChecker: created");
-    }
-    
-    ~DupChecker()
-    {
-      Dispose(false);
-    }
-  }
-}
diff --git a/tests/cli/NewFwkLib/PerfTest/LatencyListener.cs b/tests/cli/NewFwkLib/PerfTest/LatencyListener.cs
deleted file mode 100644
index 532672c..0000000
--- a/tests/cli/NewFwkLib/PerfTest/LatencyListener.cs
+++ /dev/null
@@ -1,134 +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.
- */
-
-using System;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-  //using Region = Apache.Geode.Client.IRegion<Object, Object>;
-
-  public class LatencyListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>, IDisposable
-  {
-    #region Private members
-
-    long m_maxLatency;
-    long m_minLatency = long.MaxValue;
-    long m_totLatency;
-    int m_samples;
-    int m_numAfterCreate;
-    int m_numAfterUpdate;
-
-    #endregion
-
-    #region Private methods
-
-    private void UpdateLatency(EntryEvent<TKey, TVal> ev)
-    {
-      long now = DateTime.Now.Ticks;
-      TVal newVal = ev.NewValue;
-      byte[] buffer = newVal as byte[];
-      if (buffer != null && buffer.Length >= (int)(sizeof(int) + sizeof(long)))
-      {
-        uint mark = BitConverter.ToUInt32(buffer, 0);
-        if ((mark == LatencyPutsTask<TKey, TVal>.LatMark))
-        {
-          long sendTime = BitConverter.ToInt64(buffer, 4);
-          long latency = Math.Abs(DateTime.Now.Ticks - sendTime);
-          m_minLatency = Math.Min(latency, m_minLatency);
-          m_maxLatency = Math.Max(latency, m_maxLatency);
-          m_totLatency += latency;
-          m_samples++;
-          //FwkTest.CurrentTest.FwkInfo("LatencyListener::Average: {0}",
-          //  (int)(m_totLatency / (long)m_samples));
-        }
-      }
-    }
-
-    #endregion
-
-    #region ICacheListener Members
-
-    public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterCreate;
-      UpdateLatency(ev);
-    }
-
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterUpdate;
-      UpdateLatency(ev);
-    }
-
-    
-    #endregion
-
-    protected virtual void Dispose(bool disposing)
-    {
-      string tag;
-      try
-      {
-        FwkTaskData taskData = (FwkTaskData)Util.BBGet(
-          "LatencyBB", "LatencyTag");
-        tag = taskData.GetLogString();
-      }
-      catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-      {
-        tag = null;
-      }
-      if (tag == null)
-      {
-        tag = "No tag found";
-      }
-      long avgLatency = 0;
-      FwkTest<TKey, TVal> currTest = FwkTest<TKey, TVal>.CurrentTest;
-      if (m_samples != 0)
-      {
-        avgLatency = m_totLatency / (long)m_samples;
-        currTest.FwkInfo("LatencyCSV,MinMaxAvgSamples,{0},{1},{2},{3},{4}",
-          tag, m_minLatency, m_maxLatency, avgLatency, m_samples);
-        currTest.FwkInfo("LatencySuite: {0} results: {1} min, {2} max, {3} avg, {4} samples. {5}",
-          tag, m_minLatency, m_maxLatency, avgLatency, m_samples, m_totLatency);
-        currTest.FwkInfo("Latency listener counters for {0}  afterCreate: {1}, afterUpdate: {2}",
-          tag, m_numAfterCreate, m_numAfterUpdate);
-      }
-      else
-      {
-        currTest.FwkInfo("LatencySuite: {0} results: NO DATA SAMPLES TO REPORT ON.", tag);
-        currTest.FwkInfo("Latency listener counters for {0}  afterCreate: {1}, afterUpdate: {2}",
-          tag, m_numAfterCreate, m_numAfterUpdate);
-      }
-    }
-
-    #region IDisposable Members
-
-    public void Dispose()
-    {
-      Dispose(true);
-      GC.SuppressFinalize(this);
-    }
-
-    #endregion
-
-    ~LatencyListener()
-    {
-      Dispose(false);
-    }
-  }
-}
diff --git a/tests/cli/NewFwkLib/PerfTest/PerfTasks.cs b/tests/cli/NewFwkLib/PerfTest/PerfTasks.cs
deleted file mode 100644
index 7543204..0000000
--- a/tests/cli/NewFwkLib/PerfTest/PerfTasks.cs
+++ /dev/null
@@ -1,338 +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.
- */
-
-using System;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-  //using Region = Apache.Geode.Client.IRegion<Object, Object>;
-  //using IntRegion = Apache.Geode.Client.IRegion<int, byte[]>;
-  //using StringRegion = Apache.Geode.Client.IRegion<string, byte[]>;
-
-  public class PutsTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private TKey[] m_keys;
-    private TVal[] m_values;
-
-    #endregion
-
-    #region Public accessors
-
-    public TVal[] Values
-    {
-      get
-      {
-        return m_values;
-      }
-      set
-      {
-        m_values = value;
-      }
-    }
-
-    #endregion
-
-    public PutsTask(IRegion<TKey, TVal> region, TKey[] keys,
-      TVal[] values)
-      : base()
-    {
-      m_region = region as IRegion<TKey, TVal>;
-      m_keys = keys as TKey[];
-      m_values = values as TVal[];
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      if (m_keys != null && m_keys.Length > 0)
-      {
-        int numKeys = m_keys.Length;
-        int offset = Util.Rand(numKeys);
-        int count = offset;
-        Util.Log("PutsTask::DoTask: starting {0} iterations.", iters);
-        while (Running && (iters-- != 0))
-        {
-          int idx = count % numKeys;
-          try
-          {
-            m_region[m_keys[idx]] = m_values[idx];
-            //Util.Log("rjk: puttask ---- idx = {0} key is {1} and value is {2} size of {3}", idx, m_keys[idx], m_values[idx].ToString(), m_values[idx].ToString().Length);
-          }
-          catch (Exception ex)
-          {
-            Util.Log(Util.LogLevel.Error,
-              "Exception while putting key[{0}] for region {1} in iteration " +
-              "{2}: {3}", idx, m_region.Name, (count - offset), ex);
-            throw;
-          }
-          count++;
-          //if ((count % 1000) == 0)
-          //{
-          //  Util.Log("PutsTask::DoTask: Intermediate: Ran for 1000 iterations.");
-          //}
-        }
-        //Util.Log("PutsTask::DoTask: Ran for {0} iterations.", count);
-        Interlocked.Add(ref m_iters, count - offset);
-      }
-    }
-  }
-
-  public class LatencyPutsTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private TKey[] m_keys;
-    private TVal[] m_values;
-    private int m_opsSec;
-
-    #endregion
-
-    #region Public accessors
-
-    public TVal[] Values
-    {
-      get
-      {
-        return m_values;
-      }
-      set
-      {
-        m_values = value;
-      }
-    }
-
-    #endregion
-
-    public const uint LatMark = 0x55667788;
-
-    public LatencyPutsTask(IRegion<TKey, TVal> region, TKey[] keys,
-      TVal[] values, int opsSec)
-      : base()
-    {
-      m_region = region;
-      m_keys = keys;
-      m_values = values;
-      m_opsSec = opsSec;
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      if (m_keys != null && m_keys.Length > 0)
-      {
-        TKey key = m_keys[0];
-        TVal buffer = m_values[0];
-        //TVal[] buffer = value;
-        int count = 0;
-        PaceMeter pm = new PaceMeter(m_opsSec);
-        while (Running && (iters-- != 0))
-        {
-          /*
-          if (buffer.Length >= (int)(sizeof(int) + sizeof(long)))
-          {
-            BitConverter.GetBytes(LatMark).CopyTo(buffer, 0);
-            BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(buffer, (int)(sizeof(int)));
-          }
-          */
-          try
-          {
-            m_region[key] = buffer;
-          }
-          catch (Exception ex)
-          {
-            Util.Log(Util.LogLevel.Error,
-              "Exception while putting key[{0}] for region {1} in iteration " +
-              "{2}: {3}", 0, m_region.Name, count, ex);
-            throw;
-          }
-          count++;
-          pm.CheckPace();
-        }
-        Interlocked.Add(ref m_iters, count);
-      }
-    }
-  }
-
-  public class MeteredPutsTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private TKey[] m_keys;
-    private TVal[] m_values;
-    private int m_opsSec;
-
-    #endregion
-
-    #region Public accessors
-
-    public TVal[] Values
-    {
-      get
-      {
-        return m_values;
-      }
-      set
-      {
-        m_values = value;
-      }
-    }
-
-    #endregion
-
-    public MeteredPutsTask(IRegion<TKey, TVal> region, TKey[] keys, TVal[] values, int opsSec)
-      : base()
-    {
-      m_region = region;
-      m_keys = keys;
-      m_values = values;
-      m_opsSec = opsSec;
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      if (m_keys != null && m_keys.Length > 0)
-      {
-        int numKeys = m_keys.Length;
-        int offset = Util.Rand(numKeys);
-        int count = offset;
-        int idx;
-        PaceMeter pm = new PaceMeter(m_opsSec);
-        while (Running && (iters-- != 0))
-        {
-          idx = count % numKeys;
-          try
-          {
-            m_region[m_keys[idx]] = m_values[idx];
-          }
-          catch (Exception ex)
-          {
-            Util.Log(Util.LogLevel.Error,
-              "Exception while putting key[{0}] for region {1} in iteration " +
-              "{2}: {3}", idx, m_region.Name, (count - offset), ex);
-            throw;
-          }
-          count++;
-          pm.CheckPace();
-        }
-        Interlocked.Add(ref m_iters, count - offset);
-      }
-    }
-  }
-
-  public class GetsTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private TKey[] m_keys;
-
-    #endregion
-
-    public GetsTask(IRegion<TKey, TVal> region, TKey[] keys)
-      : base()
-    {
-      m_region = region;
-      m_keys = keys;
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      if (m_keys != null && m_keys.Length > 0)
-      {
-        int numKeys = m_keys.Length;
-        int offset = Util.Rand(numKeys);
-        int count = offset;
-        while (Running && (iters-- != 0))
-        {
-          TVal val = default(TVal); ;
-          int idx = count % numKeys;
-          try
-          {
-            val = m_region[m_keys[idx]];
-            //Util.Log("rjk: ---- idx = {0} key is {1} and value is {2} size of {3}", idx, m_keys[idx], val.ToString(),val.ToString().Length) ;
-          }
-          catch (Exception ex)
-          {
-            Util.Log(Util.LogLevel.Error,
-              "Exception while getting key[{0}] for region {1} in iteration " +
-              "{2}: {3}", idx, m_region.Name, (count - offset), ex);
-            throw;
-          }
-          if (val == null)
-          {
-            string exStr = string.Format("Key[{0}] not found in region {1}",
-              m_keys[idx], m_region.Name);
-            Util.Log(Util.LogLevel.Error, exStr);
-            throw new EntryNotFoundException(exStr);
-          }
-          count++;
-        }
-        Interlocked.Add(ref m_iters, count - offset);
-      }
-    }
-  }
-
-  public class DestroyTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    private IRegion<TKey, TVal> m_region;
-    private TKey[] m_keys;
-
-    #endregion
-
-    public DestroyTask(IRegion<TKey, TVal> region, TKey[] keys)
-      : base()
-    {
-      m_region = region;
-      m_keys = keys;
-    }
-
-    public override void DoTask(int iters, object data)
-    {
-      if (m_keys != null && m_keys.Length > 0)
-      {
-        int i = 0;
-        int numKeys = m_keys.Length;
-        while (Running && i < numKeys)
-        {
-          try
-          {
-            m_region.Remove(m_keys[i++]);
-          }
-          catch (EntryNotFoundException)
-          {
-          }
-          catch (Exception ex)
-          {
-            Util.Log(Util.LogLevel.Error,
-              "Exception while destroying key[{0}] for region {1}: {2}",
-              i, m_region.Name, ex);
-            throw;
-          }
-        }
-        Interlocked.Add(ref m_iters, i);
-      }
-    }
-  }
-}
diff --git a/tests/cli/NewFwkLib/PerfTest/PerfTestCacheListener.cs b/tests/cli/NewFwkLib/PerfTest/PerfTestCacheListener.cs
deleted file mode 100644
index 4ba0d29..0000000
--- a/tests/cli/NewFwkLib/PerfTest/PerfTestCacheListener.cs
+++ /dev/null
@@ -1,216 +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.
- */
-
-using System;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-  //using Region = Apache.Geode.Client.IRegion<Object, Object>;
-
-  public class PerfTestCacheListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>, IDisposable
-  {
-    #region Private members
-
-    int m_numAfterCreate;
-    int m_numAfterUpdate;
-    int m_numAfterInvalidate;
-    int m_numAfterDestroy;
-    int m_numAfterRegionInvalidate;
-    int m_numAfterRegionClear;
-    int m_numAfterRegionDestroy;
-    int m_numClose;
-    int m_sleep;
-
-    #endregion
-
-    #region ICacheListener Members
-
-    public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numAfterCreate;
-    }
-
-    public override void AfterDestroy(EntryEvent<TKey, TVal> ev)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numAfterDestroy;
-
-    }
-
-    public override void AfterInvalidate(EntryEvent<TKey, TVal> ev)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numAfterInvalidate;
-    }
-
-    public override void AfterRegionClear(RegionEvent<TKey, TVal> ev)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numAfterRegionClear;
-    }
-
-    public override void AfterRegionDestroy(RegionEvent<TKey, TVal> ev)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numAfterRegionDestroy;
-    }
-
-    public override void AfterRegionInvalidate(RegionEvent<TKey, TVal> ev)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numAfterRegionInvalidate;
-    }
-
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numAfterUpdate;
-    }
-
-    public override void Close(IRegion<TKey, TVal> region)
-    {
-      if (m_sleep > 0)
-      {
-        Thread.Sleep(m_sleep);
-      }
-      ++m_numClose;
-    }
-  
-    public void Reset(int sleepTime)
-    {
-      m_sleep = sleepTime;
-      m_numAfterCreate = m_numAfterUpdate = m_numAfterInvalidate = 0;
-      m_numAfterDestroy = m_numAfterRegionClear = m_numAfterRegionInvalidate =
-        m_numAfterRegionDestroy = m_numClose = 0;
-    }
-
-    #endregion
-
-    protected virtual void Dispose(bool disposing)
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("PerfTestCacheListener invoked afterCreate: {0}," +
-        " afterUpdate: {1}, afterInvalidate: {2}, afterDestroy: {3}," +
-        " afterRegionInvalidate: {4}, afterRegionDestroy: {5}, region close: {6}, afterRegionClear: {7}",
-        m_numAfterCreate, m_numAfterUpdate, m_numAfterInvalidate, m_numAfterDestroy,
-        m_numAfterRegionInvalidate, m_numAfterRegionDestroy, m_numClose,
-	m_numAfterRegionClear);
-    }
-
-    #region IDisposable Members
-
-    public void Dispose()
-    {
-      Dispose(true);
-      GC.SuppressFinalize(this);
-    }
-
-    #endregion
-
-    ~PerfTestCacheListener()
-    {
-      Dispose(false);
-    }
-  }
-  public class ConflationTestCacheListener<TKey, TVal> : CacheListenerAdapter<TKey, TVal>
-  {
-    int m_numAfterCreate;
-    int m_numAfterUpdate;
-    int m_numAfterInvalidate;
-    int m_numAfterDestroy;
-    
-    public ConflationTestCacheListener() 
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("Calling non durable client ConflationTestCacheListener");
-      m_numAfterCreate = 0;
-      m_numAfterUpdate = 0;
-      m_numAfterInvalidate = 0;
-      m_numAfterDestroy = 0;
-      
-    }
-
-    public static ICacheListener<TKey, TVal> Create()
-    {
-      return new ConflationTestCacheListener<TKey, TVal>();
-    }
-    ~ConflationTestCacheListener() { }
-    
-    #region ICacheListener Members
-
-    public override void AfterCreate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterCreate;
-    }
-
-    public override void AfterUpdate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterUpdate;
-     }
-    public override void AfterRegionLive(RegionEvent<TKey, TVal> ev)
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("ConflationTestCacheListener: AfterRegionLive invoked");
-    }
-    public override void AfterDestroy(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterDestroy;
-    }
-
-    public override void AfterInvalidate(EntryEvent<TKey, TVal> ev)
-    {
-      ++m_numAfterInvalidate;
-    }
-
-    public override void AfterRegionDestroy(RegionEvent<TKey, TVal> ev)
-    {
-      dumpToBB(ev.Region);
-    }
-
-    private void dumpToBB(IRegion<TKey, TVal> region)
-    {
-      FwkTest<TKey, TVal>.CurrentTest.FwkInfo("dumping non durable client data on BB for ConflationTestCacheListener");
-      Util.BBSet("ConflationCacheListener", "AFTER_CREATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterCreate);
-      Util.BBSet("ConflationCacheListener", "AFTER_UPDATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterUpdate);
-      Util.BBSet("ConflationCacheListener", "AFTER_DESTROY_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterDestroy);
-      Util.BBSet("ConflationCacheListener", "AFTER_INVALIDATE_COUNT_" + Util.ClientId + "_" + region.Name, m_numAfterInvalidate);
-    }
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/PerfTest/PerfTests.cs b/tests/cli/NewFwkLib/PerfTest/PerfTests.cs
deleted file mode 100644
index f02422c..0000000
--- a/tests/cli/NewFwkLib/PerfTest/PerfTests.cs
+++ /dev/null
@@ -1,1483 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client;
-  //using Region = Apache.Geode.Client.IRegion<Object, Object>;
-  //using IntRegion = Apache.Geode.Client.IRegion<int, byte[]>;
-  //using StringRegion = Apache.Geode.Client.IRegion<string, byte[]>;
-  public class PerfTests<TKey, TVal> : FwkTest<TKey, TVal>
-  {
-    #region Protected members
-    protected TKey[] m_keysA;
-    protected int m_maxKeys;
-    protected int m_keyIndexBegin;
-
-    protected TVal[] m_cValues;
-    protected int m_maxValues;
-
-    public char m_keyType = 'i';
-
-    #endregion
-
-    #region Protected constants
-
-    protected const string ClientCount = "clientCount";
-    protected const string TimedInterval = "timedInterval";
-    protected const string DistinctKeys = "distinctKeys";
-    protected const string NumThreads = "numThreads";
-    protected const string ValueSizes = "valueSizes";
-    protected const string OpsSecond = "opsSecond";
-    protected const string KeyType = "keyType";
-    protected const string KeySize = "keySize";
-    protected const string KeyIndexBegin = "keyIndexBegin";
-    protected const string RegisterKeys = "registerKeys";
-    protected const string RegisterRegex = "registerRegex";
-    protected const string UnregisterRegex = "unregisterRegex";
-    protected const string ExpectedCount = "expectedCount";
-    protected const string InterestPercent = "interestPercent";
-    protected const string KeyStart = "keyStart";
-    protected const string KeyEnd = "keyEnd";
-
-    #endregion
-    
-    #region Protected utility methods
-
-    protected void ClearKeys()
-    {
-      if (m_keysA != null)
-      {
-        for (int i = 0; i < m_keysA.Length; i++)
-        {
-          if (m_keysA[i] != null)
-          {
-            //m_keysA[i];
-            m_keysA[i] = default(TKey);
-          }
-        }
-        m_keysA = null;
-        m_maxKeys = 0;
-      }
-    }
-
-    protected int InitKeys(bool useDefault)
-    {
-      string typ = GetStringValue(KeyType); // int is only value to use
-      char newType = (typ == null || typ.Length == 0) ? 's' : typ[0];
-
-      int low = GetUIntValue(KeyIndexBegin);
-      low = (low > 0) ? low : 0;
-      //ResetKey(DistinctKeys);
-      int numKeys = GetUIntValue(DistinctKeys);  // check distinct keys first
-      if (numKeys <= 0)
-      {
-        if (useDefault)
-        {
-          numKeys = 5000;
-        }
-        else
-        {
-          //FwkSevere("Failed to initialize keys with numKeys: {0}", numKeys);
-          return numKeys;
-        }
-      }
-      int high = numKeys + low;
-      FwkInfo("InitKeys:: numKeys: {0}; low: {1}", numKeys, low);
-      if ((newType == m_keyType) && (numKeys == m_maxKeys) &&
-        (m_keyIndexBegin == low))
-      {
-        return numKeys;
-      }
-
-      ClearKeys();
-      m_maxKeys = numKeys;
-      m_keyIndexBegin = low;
-      m_keyType = newType;
-      if (m_keyType == 'i')
-      {
-        InitIntKeys(low, high);
-      }
-      else
-      {
-        int keySize = GetUIntValue(KeySize);
-        keySize = (keySize > 0) ? keySize : 10;
-        string keyBase = new string('A', keySize);
-        InitStrKeys(low, high, keyBase);
-      }
-      for (int j = 0; j < numKeys; j++)
-      {
-        int randIndx = Util.Rand(numKeys);
-        if (randIndx != j)
-        {
-          TKey tmp = m_keysA[j];
-          m_keysA[j] = m_keysA[randIndx];
-          m_keysA[randIndx] = tmp;
-        }
-      }
-      return m_maxKeys;
-    }
-
-    protected int InitKeys()
-    {
-      return InitKeys(true);
-    }
-
-    protected void InitStrKeys(int low, int high, string keyBase)
-    {
-      m_keysA = (TKey[])(object) new String[m_maxKeys];
-      FwkInfo("m_maxKeys: {0}; low: {1}; high: {2}",
-        m_maxKeys, low, high);
-      for (int i = low; i < high; i++)
-      {
-        m_keysA[i - low] = (TKey)(object)(keyBase.ToString()  + i.ToString("D10"));
-      }
-    }
-
-    protected void InitIntKeys(int low, int high)
-    {
-      m_keysA = (TKey[])(object) new Int32[m_maxKeys];
-      FwkInfo("m_maxKeys: {0}; low: {1}; high: {2}",
-        m_maxKeys, low, high);
-      for (int i = low; i < high; i++)
-      {
-        m_keysA[i - low] = (TKey)(object)i;
-      }
-    }
-
-    protected int InitValues(int numKeys)
-    {
-      return InitValues(numKeys, 0);
-    }
-
-    protected int InitValues(int numKeys, int size)
-    {
-      if (size <= 0)
-      {
-        size = GetUIntValue(ValueSizes);
-      }
-      if (size <= 0)
-      {
-        //FwkSevere("Failed to initialize values with valueSize: {0}", size);
-        return size;
-      }
-      if (numKeys <= 0)
-      {
-        numKeys = 500;
-      }
-      m_maxValues = numKeys;
-      if (m_cValues != null)
-      {
-        for (int i = 0; i < m_cValues.Length; i++)
-        {
-          if (m_cValues[i] != null)
-          {
-            //m_cValues[i].Dispose();
-            m_cValues[i] = default(TVal);
-          }
-        }
-        m_cValues = null;
-      }
-
-      m_cValues = new TVal[m_maxValues];
-
-      FwkInfo("InitValues()  payload size: {0}", size);
-      //byte[] createPrefix = Encoding.ASCII.GetBytes("Create ");
-      //byte[] buffer = new byte[size];
-      for (int i = 0; i < m_maxValues; i++)
-      {
-        
-        StringBuilder builder = new StringBuilder();
-        Random random = new Random();
-        char ch;
-        for (int j = 0; j < size; j++)
-        {
-          ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
-          builder.Append(ch);
-        }
-
-        //FwkInfo("rjk: InitValues()   value {0}", builder.ToString());
-        //Util.RandBytes(buffer);
-        //createPrefix.CopyTo(buffer, 0);
-        //string tmp = buffer;
-        if (typeof(TVal) == typeof(string))
-        {
-          m_cValues[i] = (TVal)(object)builder.ToString();
-          //FwkInfo("rjk: InitValues()   value {0} size is {1}", m_cValues[i].ToString(), m_cValues[i].ToString().Length);
-        }
-        else if (typeof(TVal) == typeof(byte[]))
-        {
-          //Encoding.ASCII.GetBytes(buffer);
-          //Util.RandBytes(buffer);
-          //createPrefix.CopyTo(buffer, 0);
-          m_cValues[i] = (TVal)(object)(Encoding.ASCII.GetBytes(builder.ToString()));
-          //FwkInfo("rjk: InitValues() type is byte[]  value {0} size is {1}", m_cValues[i].ToString(), ((byte[])(object)m_cValues[i]).Length);
-        }
-         
-        /*
-        Util.RandBytes(buffer);
-        createPrefix.CopyTo(buffer, 0);
-        if (typeof(TVal) == typeof(string))
-        {
-          String MyString;
-          //Encoding ASCIIEncod = new Encoding();
-          MyString = Encoding.ASCII.GetString(buffer);
-          m_cValues[i] = (TVal)(MyString as object);
-          FwkInfo("rjk: InitValues()   value {0} size is {1}", MyString.ToString(), m_cValues[i].ToString().Length);
-        }
-        else if (typeof(TVal) == typeof(byte[]))
-        {
-          Util.RandBytes(buffer);
-          createPrefix.CopyTo(buffer, 0);
-          m_cValues[i] = (TVal)(buffer as object);
-        }
-         * */
-        //for (int ii = 0; ii < buffer.Length; ++ii)
-        //{
-        //  FwkInfo("rjk: InitValues() index is {0} value is {1} buffer = {2}", i, m_cValues[ii], buffer[ii]);
-        //}
-      }
-      return size;
-    }
-
-    protected IRegion<TKey, TVal> GetRegion()
-    {
-      return GetRegion(null);
-     
-    }
-
-
-    protected IRegion<TKey, TVal> GetRegion(string regionName)
-    {
-      IRegion<TKey, TVal> region;
-      if (regionName == null)
-      {
-          regionName = GetStringValue("regionName");
-      }
-      if (regionName == null)
-      {
-        region = GetRootRegion();
-        if (region == null)
-        {
-          IRegion<TKey, TVal>[] rootRegions = CacheHelper<TKey, TVal>.DCache.RootRegions<TKey, TVal>();
-          if (rootRegions != null && rootRegions.Length > 0)
-          {
-            region = rootRegions[Util.Rand(rootRegions.Length)];
-          }
-        }
-      }
-      else
-      {
-        region = CacheHelper<TKey, TVal>.GetRegion(regionName);
-      }
-      return region;
-    }
-
-    #endregion
-
-    #region Public methods
-
-    public static ICacheListener<TKey, TVal> CreatePerfTestCacheListener()
-    {
-      return new PerfTestCacheListener<TKey, TVal>();
-    }
-    public static ICacheListener<TKey, TVal> CreateConflationTestCacheListener()
-    {
-      return new ConflationTestCacheListener<TKey, TVal>();
-    }
-    public static ICacheListener<TKey, TVal> CreateLatencyListenerP()
-    {
-      return new LatencyListener<TKey, TVal>();
-    }
-
-    public static ICacheListener<TKey, TVal> CreateDupChecker()
-    {
-      return new DupChecker<TKey, TVal>();
-    }
-
-    public virtual void DoCreateRegion()
-    {
-      FwkInfo("In DoCreateRegion()");
-      try
-      {
-        IRegion<TKey,TVal> region = null;
-
-        FwkInfo("Tkey = {0} , Val = {1}", typeof(TKey).Name, typeof(TVal));
-        
-        region = CreateRootRegion();
-        if (region == null)
-        {
-          FwkException("DoCreateRegion()  could not create region.");
-        }
-        FwkInfo("DoCreateRegion()  Created region '{0}'", region.Name);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreateRegion() complete.");
-    }
-
-    public void DoCloseCache()
-    {
-      FwkInfo("DoCloseCache()  Closing cache and disconnecting from" +
-        " distributed system.");
-      CacheHelper<TKey,TVal>.Close();
-    }
-
-    public void DoPuts()
-    {
-      FwkInfo("In DoPuts()");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        int numClients = GetUIntValue(ClientCount);
-        string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        int timedInterval = GetTimeValue(TimedInterval) * 1000;
-        if (timedInterval <= 0)
-        {
-          timedInterval = 5000;
-        }
-        int maxTime = 10 * timedInterval;
-
-        // Loop over key set sizes
-        ResetKey(DistinctKeys);
-        int numKeys;
-        while ((numKeys = InitKeys(false)) > 0)
-        { // keys loop
-          // Loop over value sizes
-          ResetKey(ValueSizes);
-          int valSize;
-          while ((valSize = InitValues(numKeys)) > 0)
-          { // value loop
-            // Loop over threads
-            ResetKey(NumThreads);
-            int numThreads;
-            while ((numThreads = GetUIntValue(NumThreads)) > 0)
-            {
-              try
-              {
-                //if (m_keyType == 's')
-                //{
-                  //StringRegion sregion = region as StringRegion;
-                  PutsTask<TKey, TVal> puts = new PutsTask<TKey, TVal>(region, m_keysA, m_cValues);
-                  FwkInfo("Running warmup task for {0} iterations.", numKeys);
-                  RunTask(puts, 1, numKeys, -1, -1, null);
-                  // Running the warmup task
-                  Thread.Sleep(3000);
-                  // And we do the real work now
-                  FwkInfo("Running timed task for {0} secs and {1} threads; numKeys[{2}]",
-                    timedInterval / 1000, numThreads, numKeys);
-                  SetTaskRunInfo(label, "Puts", m_maxKeys, numClients,
-                    valSize, numThreads);
-                  RunTask(puts, numThreads, -1, timedInterval, maxTime, null);
-                  AddTaskRunRecord(puts.Iterations, puts.ElapsedTime);
-
-              }
-              catch (ClientTimeoutException)
-              {
-                FwkException("In DoPuts()  Timed run timed out.");
-              }
-              Thread.Sleep(3000); // Put a marker of inactivity in the stats
-            }
-            Thread.Sleep(3000); // Put a marker of inactivity in the stats
-          } // value loop
-          Thread.Sleep(3000); // Put a marker of inactivity in the stats
-        } // keys loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPuts() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000); // Put a marker of inactivity in the stats
-      FwkInfo("DoPuts() complete.");
-    }
-    public void DoPopulateRegion()
-    {
-      FwkInfo("In DoPopulateRegion()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        int numKeys = InitKeys();
-        InitValues(numKeys);
-
-        PutsTask<TKey, TVal> puts = new PutsTask<TKey, TVal>(region, m_keysA, m_cValues);
-        FwkInfo("Populating region.");
-        RunTask(puts, 1, m_maxKeys, -1, -1, null);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPopulateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoPopulateRegion() complete.");
-    }
-    
-    public void DoSerialPuts()
-    {
-      FwkInfo("In DoSerialPuts()");
-      try
-      {
-        IRegion<int, int> region = (IRegion<int, int>)GetRegion();
-
-        int keyStart = GetUIntValue(KeyStart);
-        int keyEnd = GetUIntValue(KeyEnd);
-
-        for (Int32 keys = keyStart; keys <= keyEnd; keys++)
-        {
-          if (keys % 50 == 1)
-          {
-            FwkInfo("DoSerialPuts() putting 1000 values for key " + keys);
-          }
-
-          Int32 key = keys;
-          for (Int32 values = 1; values <= 1000; values++)
-          {
-            Int32 value = values;
-            region[key] =  value;
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoSerialPuts() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000); // Put a marker of inactivity in the stats
-      FwkInfo("DoSerialPuts() complete.");
-    }
-
-    public void DoPutBursts()
-    {
-      FwkInfo("In DoPutBursts()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        int numClients = GetUIntValue(ClientCount);
-        string label = CacheHelper<TKey,TVal>.RegionTag(region.Attributes);
-
-        int timedInterval = GetTimeValue(TimedInterval) * 1000;
-        if (timedInterval <= 0)
-        {
-          timedInterval = 5000;
-        }
-        int burstMillis = GetUIntValue("burstMillis");
-        if (burstMillis <= 0)
-        {
-          burstMillis = 500;
-        }
-        int burstPause = GetTimeValue("burstPause") * 1000;
-        if (burstPause <= 0)
-        {
-          burstPause = 1000;
-        }
-        int opsSec = GetUIntValue(OpsSecond);
-        if (opsSec <= 0)
-        {
-          opsSec = 100;
-        }
-
-        // Loop over key set sizes
-        ResetKey(DistinctKeys);
-        int numKeys;
-        while ((numKeys = InitKeys(false)) > 0)
-        { // keys loop
-          // Loop over value sizes
-          ResetKey(ValueSizes);
-          int valSize;
-          while ((valSize = InitValues(numKeys)) > 0)
-          { // value loop
-            // Loop over threads
-            ResetKey(NumThreads);
-            int numThreads;
-            while ((numThreads = GetUIntValue(NumThreads)) > 0)
-            { // thread loop
-              // And we do the real work now
-              MeteredPutsTask<TKey, TVal> mputs = new MeteredPutsTask<TKey, TVal>(region, m_keysA,
-                m_cValues, opsSec);
-              FwkInfo("Running warmup metered task for {0} iterations.", m_maxKeys);
-              RunTask(mputs, 1, m_maxKeys, -1, -1, null);
-              Thread.Sleep(10000);
-              PutsTask<TKey, TVal> puts = new PutsTask<TKey, TVal>(region, m_keysA, m_cValues);
-              int loopIters = (timedInterval / burstMillis) + 1;
-              FwkInfo("Running timed task for {0} secs and {1} threads.",
-                timedInterval/1000, numThreads);
-              SetTaskRunInfo(label, "PutBursts", numKeys, numClients,
-                valSize, numThreads);
-              int totIters = 0;
-              TimeSpan totTime = TimeSpan.Zero;
-              for (int i = loopIters; i > 0; i--)
-              {
-                try
-                {
-                  RunTask(puts, numThreads, -1, burstMillis, 30000, null);
-                }
-                catch (ClientTimeoutException)
-                {
-                  FwkException("In DoPutBursts()  Timed run timed out.");
-                }
-                totIters += puts.Iterations;
-                totTime += puts.ElapsedTime;
-                double psec = (totIters * 1000.0) / totTime.TotalMilliseconds;
-                FwkInfo("PerfSuite interim: {0} {1} {2}", psec, totIters, totTime);
-                Thread.Sleep(burstPause);
-              }
-              AddTaskRunRecord(totIters, totTime);
-              // real work complete for this pass thru the loop
-
-              Thread.Sleep(3000); // Put a marker of inactivity in the stats
-            } // thread loop
-            Thread.Sleep(3000); // Put a marker of inactivity in the stats
-          } // value loop
-          Thread.Sleep(3000); // Put a marker of inactivity in the stats
-        } // keys loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPutBursts() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000); // Put a marker of inactivity in the stats
-      FwkInfo("DoPutBursts() complete.");
-    }
-
-    public void DoLatencyPuts()
-    {
-      FwkInfo("In DoLatencyPuts()");
-
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        int numClients = GetUIntValue(ClientCount);
-        string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        int timedInterval = GetTimeValue(TimedInterval) * 1000;
-        if (timedInterval <= 0)
-        {
-          timedInterval = 5000;
-        }
-        int maxTime = 10 * timedInterval;
-
-        int opsSec = GetUIntValue(OpsSecond);
-        if (opsSec < 0)
-        {
-          opsSec = 100;
-        }
-        // Loop over key set sizes
-        ResetKey(DistinctKeys);
-        int numKeys;
-        while ((numKeys = InitKeys(false)) > 0)
-        { // keys loop
-          // Loop over value sizes
-          ResetKey(ValueSizes);
-          int valSize;
-          while ((valSize = InitValues(numKeys)) > 0)
-          { // value loop
-            // Loop over threads
-            ResetKey(NumThreads);
-            int numThreads;
-            while ((numThreads = GetUIntValue(NumThreads)) > 0)
-            {
-              LatencyPutsTask<TKey, TVal> puts = new LatencyPutsTask<TKey, TVal>(region, m_keysA,
-                m_cValues, opsSec);
-              // Running the warmup task
-              FwkInfo("Running warmup task for {0} iterations.", numKeys);
-              RunTask(puts, 1, numKeys, -1, -1, null);
-              Thread.Sleep(3000);
-              // And we do the real work now
-              FwkInfo("Running timed task for {0} secs and {1} threads.",
-                timedInterval/1000, numThreads);
-              SetTaskRunInfo(label, "LatencyPuts", numKeys, numClients, valSize, numThreads);
-              Util.BBSet("LatencyBB", "LatencyTag", TaskData);
-              try
-              {
-                RunTask(puts, numThreads, -1, timedInterval, maxTime, null);
-              }
-              catch (ClientTimeoutException)
-              {
-                FwkException("In DoLatencyPuts()  Timed run timed out.");
-              }
-              AddTaskRunRecord(puts.Iterations, puts.ElapsedTime);
-              // real work complete for this pass thru the loop
-              Thread.Sleep(3000); // Put a marker of inactivity in the stats
-            } // thread loop
-            Thread.Sleep(3000); // Put a marker of inactivity in the stats
-          } // value loop
-          Thread.Sleep(3000); // Put a marker of inactivity in the stats
-        } // keys loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoLatencyPuts() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000); // Put a marker of inactivity in the stats
-      FwkInfo("DoLatencyPuts() complete.");
-    }
-
-    public void DoGets()
-    {
-      FwkInfo("In DoGets()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        FwkInfo("rjk:DoGets region name is {0} ", region.Name); 
-        int numClients = GetUIntValue(ClientCount);
-        string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        int timedInterval = GetTimeValue(TimedInterval) * 1000;
-        if (timedInterval <= 0)
-        {
-          timedInterval = 5000;
-        }
-        int maxTime = 10 * timedInterval;
-
-        ResetKey(DistinctKeys);
-        InitKeys();
-
-        int valSize = GetUIntValue(ValueSizes);
-        FwkInfo("rjk:DoGets number of keys in region is {0} .", region.Keys.Count);
-        // Loop over threads
-        ResetKey(NumThreads);
-        int numThreads;
-        while ((numThreads = GetUIntValue(NumThreads)) > 0)
-        { // thread loop
-
-          // And we do the real work now
-          GetsTask<TKey, TVal> gets = new GetsTask<TKey, TVal>(region, m_keysA);
-          FwkInfo("Running warmup task for {0} iterations.", m_maxKeys);
-          RunTask(gets, 1, m_maxKeys, -1, -1, null);
-          region.GetLocalView().InvalidateRegion();
-          Thread.Sleep(3000);
-          FwkInfo("Running timed task for {0} secs and {1} threads.",
-            timedInterval/1000, numThreads);
-          SetTaskRunInfo(label, "Gets", m_maxKeys, numClients, valSize, numThreads);
-          try
-          {
-            RunTask(gets, numThreads, -1, timedInterval, maxTime, null);
-          }
-          catch (ClientTimeoutException)
-          {
-            FwkException("In DoGets()  Timed run timed out.");
-          }
-          AddTaskRunRecord(gets.Iterations, gets.ElapsedTime);
-          // real work complete for this pass thru the loop
-
-          Thread.Sleep(3000);
-        } // thread loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoGets() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000);
-      FwkInfo("DoGets() complete.");
-    }
-
-    public void DoPopServers()
-    {
-      FwkInfo("In DoPopServers()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        int numKeys = InitKeys();
-
-        ResetKey(ValueSizes);
-        InitValues(numKeys);
-
-        int opsSec = GetUIntValue(OpsSecond);
-
-        MeteredPutsTask<TKey, TVal> mputs = new MeteredPutsTask<TKey, TVal>(region, m_keysA,
-          m_cValues, opsSec);
-        RunTask(mputs, 1, m_maxKeys, -1, -1, null);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPopServers() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoPopServers() complete.");
-    }
-
-    public void DoPopClient()
-    {
-      FwkInfo("In DoPopClient()");
-
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        InitKeys();
-
-        GetsTask<TKey, TVal> gets = new GetsTask<TKey, TVal>(region, m_keysA);
-        RunTask(gets, 1, m_maxKeys, -1, -1, null);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPopClient() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DopopClient() complete.");
-    }
-
-    public void DoPopClientMS()
-    {
-      FwkInfo("In DoPopClientMS()");
-
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        int numKeys = GetUIntValue(DistinctKeys);
-        int clientCount = GetUIntValue(ClientCount);
-        int interestPercent = GetUIntValue(InterestPercent);
-        if (interestPercent <= 0)
-        {
-          if (clientCount <= 0)
-          {
-            interestPercent = 100;
-          }
-          else
-          {
-            interestPercent = (100 / clientCount);
-          }
-        }
-        int myNumKeys = (numKeys * interestPercent) / 100;
-        int myNum = Util.ClientNum;
-        int myStart = myNum * myNumKeys;
-        int myValSize = 10;
-        m_maxKeys = numKeys;
-        InitIntKeys(myStart, myStart + myNumKeys);
-        InitValues(myNumKeys, myValSize);
-
-        FwkInfo("DoPopClientMS() Client number: {0}, Client count: {1}, " +
-          "MaxKeys: {2}", myNum, clientCount, m_maxKeys);
-        PutsTask<TKey, TVal> puts = new PutsTask<TKey, TVal>(region, m_keysA, m_cValues);
-        RunTask(puts, 1, m_maxKeys, -1, -1, null);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPopClientMS() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoPopClientMS() complete.");
-    }
-
-    public void DoDestroys()
-    {
-      FwkInfo("In DoDestroys()");
-
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        int numClients = GetUIntValue(ClientCount);
-        FwkInfo("DoDestroys() numclients set to {0}", numClients);
-        string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        int timedInterval = GetTimeValue(TimedInterval) * 1000;
-        if (timedInterval <= 0)
-        {
-          timedInterval = 5000;
-        }
-        int maxTime = 10 * timedInterval;
-
-        // always use only one thread for destroys.
-        int numKeys;
-        // Loop over distinctKeys
-        while ((numKeys = InitKeys(false)) > 0)
-        { // thread loop
-          int valSize = InitValues(numKeys);
-          // And we do the real work now
-
-          //populate the region
-          PutsTask<TKey, TVal> puts = new PutsTask<TKey, TVal>(region, m_keysA, m_cValues);
-          FwkInfo("DoDestroys() Populating region.");
-          RunTask(puts, 1, m_maxKeys, -1, -1, null);
-          DestroyTask<TKey, TVal> destroys = new DestroyTask<TKey, TVal>(region, m_keysA);
-          FwkInfo("Running timed task for {0} iterations and {1} threads.",
-            numKeys, 1);
-          SetTaskRunInfo(label, "Destroys", numKeys, numClients, valSize, 1);
-          try
-          {
-            RunTask(destroys, 1, numKeys, -1, maxTime, null);
-          }
-          catch (ClientTimeoutException)
-          {
-            FwkException("In DoDestroys()  Timed run timed out.");
-          }
-          AddTaskRunRecord(destroys.Iterations, destroys.ElapsedTime);
-          // real work complete for this pass thru the loop
-
-          Thread.Sleep(3000);
-        } // distinctKeys loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoDestroys() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000);
-      FwkInfo("DoDestroys() complete.");
-    }
-
-    public void DoCheckValues()
-    {
-      FwkInfo("In DoCheckValues()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ICollection<TVal> vals = region.Values;
-        int creates = 0;
-        int updates = 0;
-        int unknowns = 0;
-        if (vals != null)
-        {
-          byte[] createPrefix = Encoding.ASCII.GetBytes("Create ");
-          byte[] updatePrefix = Encoding.ASCII.GetBytes("Update ");
-          foreach (object val in vals)
-          {
-            byte[] valBytes = val as byte[];
-            if (Util.CompareArraysPrefix(valBytes, createPrefix))
-            {
-              creates++;
-            }
-            else if (Util.CompareArraysPrefix(valBytes, updatePrefix))
-            {
-              updates++;
-            }
-            else
-            {
-              unknowns++;
-            }
-          }
-          FwkInfo("DoCheckValues()  Found {0} values from creates, " +
-            "{1} values from updates, and {2} unknown values.",
-            creates, updates, unknowns);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCheckValues() Caught Exception: {0}", ex);
-      }
-    }
-
-    public void DoLocalDestroyEntries()
-    {
-      FwkInfo("In DoLocalDestroyEntries()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ICollection<TKey> keys = region.GetLocalView().Keys;
-        if (keys != null)
-        {
-          foreach (TKey key in keys)
-          {
-            region.GetLocalView().Remove(key);
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoLocalDestroyEntries() Caught Exception: {0}", ex);
-      }
-    }
-
-    public void DoDestroyRegion()
-    {
-      FwkInfo("In DoDestroyRegion");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        region.DestroyRegion();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoDestroyRegion() caught exception: {0}" , ex);
-      }
-    }
-
-    public void DoLocalDestroyRegion()
-    {
-      FwkInfo("In DoLocalDestroyRegion()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        region.GetLocalView().DestroyRegion();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoLocalDestroyRegion() Caught Exception: {0}", ex);
-      }
-    }
-
-    public void DoPutAll()
-    {
-      FwkInfo("In DoPutAll()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        int numKeys = InitKeys();
-
-        ResetKey(ValueSizes);
-        InitValues(numKeys);
-        IDictionary<TKey, TVal> map = new Dictionary<TKey, TVal>();
-        map.Clear();
-        Int32 i = 0;
-        while (i < numKeys)
-        {
-          map.Add(m_keysA[i], m_cValues[i]);
-          i++;
-        }
-        DateTime startTime;
-        DateTime endTime;
-        TimeSpan elapsedTime;
-        startTime = DateTime.Now;
-        region.PutAll(map, TimeSpan.FromSeconds(60));
-        endTime = DateTime.Now;
-        elapsedTime = endTime - startTime;
-        FwkInfo("PerfTests.DoPutAll: Time Taken to execute" +
-                " the putAll for {0}: is {1}ms", numKeys,
-                elapsedTime.TotalMilliseconds);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPutAll() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoPutAll() complete.");
-    }
-
-    public void DoGetAllAndVerification()
-    {
-      FwkInfo("In DoGetAllAndVerification()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        ResetKey(ValueSizes);
-        ResetKey("addToLocalCache");
-        ResetKey("inValidateRegion");
-        int numKeys = InitKeys(false);
-        Int32 i = 0;
-        bool isInvalidateRegion = GetBoolValue("isInvalidateRegion");
-        if (isInvalidateRegion)
-        {
-          region.GetLocalView().InvalidateRegion();
-        }
-        List<TKey> keys = new List<TKey>();
-        keys.Clear();
-        while (i < numKeys)
-        {
-          keys.Add(m_keysA[i]);
-          i++;
-        }
-        bool isAddToLocalCache = GetBoolValue("addToLocalCache");
-        Dictionary<TKey, TVal> values = new Dictionary<TKey, TVal>();
-        values.Clear();
-        DateTime startTime;
-        DateTime endTime;
-        TimeSpan elapsedTime;
-        startTime = DateTime.Now;
-        region.GetAll(keys.ToArray(), values, null, isAddToLocalCache);
-        endTime = DateTime.Now;
-        elapsedTime = endTime - startTime;
-        FwkInfo("PerfTests.DoGetAllAndVerification: Time Taken to execute" +
-                " the getAll for {0}: is {1}ms", numKeys,
-                elapsedTime.TotalMilliseconds);
-        int payload = GetUIntValue("valueSizes");
-        FwkInfo("PerfTests.DoGetAllAndVerification: keyCount = {0}" + " valueCount = {1} ",
-                 keys.Count, values.Count);
-        if (values.Count == keys.Count)
-        {
-          foreach (KeyValuePair<TKey, TVal> entry in values)
-          {
-            TVal item = entry.Value;
-            //if (item != payload) // rjk Need to check how to verify
-            //{
-            //  FwkException("PerfTests.DoGetAllAndVerification: value size {0} is not equal to " +
-            //                "expected payload size {1} for key : {2}", item.Length, payload, entry.Key);
-            //}
-          }
-        }
-        if (isAddToLocalCache)
-        {
-          if (keys.Count != region.Count)
-          {
-            FwkException("PerfTests.DoGetAllAndVerification: number of keys in region do not" +
-                 " match expected number");
-          }
-        }
-        else
-        {
-          if (region.Count != 0)
-          {
-            FwkException("PerfTests.DoGetAllAndVerification: expected zero keys in region");
-          }
-        }
-
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoGetAllAndVerification() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoGetAllAndVerification() complete.");
-    }
-    public void DoResetListener()
-    {
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        int sleepTime = GetUIntValue("sleepTime");
-        PerfTestCacheListener<TKey,TVal> listener =
-          region.Attributes.CacheListener as PerfTestCacheListener<TKey, TVal>;
-        if (listener != null)
-        {
-          listener.Reset(sleepTime);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkSevere("DoResetListener() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000);
-      FwkInfo("DoResetListener() complete.");
-    }
-
-    public void DoRegisterInterestList()
-    {
-      FwkInfo("In DoRegisterInterestList()");
-      try
-      {
-        ResetKey(DistinctKeys);
-        ResetKey(KeyIndexBegin);
-        ResetKey(RegisterKeys);
-        string typ = GetStringValue(KeyType); // int is only value to use
-        char newType = (typ == null || typ.Length == 0) ? 's' : typ[0];
-
-        IRegion<TKey,TVal> region = GetRegion();
-        int numKeys = GetUIntValue(DistinctKeys);  // check distince keys first
-        if (numKeys <= 0)
-        {
-          FwkSevere("DoRegisterInterestList() Failed to initialize keys " +
-            "with numKeys: {0}", numKeys);
-          return;
-        }
-        int low = GetUIntValue(KeyIndexBegin);
-        low = (low > 0) ? low : 0;
-        int numOfRegisterKeys = GetUIntValue(RegisterKeys);
-        int high = numOfRegisterKeys + low;
-        ClearKeys();
-        m_maxKeys = numOfRegisterKeys;
-        m_keyIndexBegin = low;
-        m_keyType = newType;
-        if (m_keyType == 'i')
-        {
-          InitIntKeys(low, high);
-        }
-        else
-        {
-          int keySize = GetUIntValue(KeySize);
-          keySize = (keySize > 0) ? keySize : 10;
-          string keyBase = new string('A', keySize);
-          InitStrKeys(low, high, keyBase);
-        }
-
-        FwkInfo("DoRegisterInterestList() registering interest for {0} to {1}",
-          low, high);
-        TKey[] registerKeyList = new TKey[high - low];
-        for (int j = low; j < high; j++)
-        {
-          if (m_keysA[j - low] != null)
-          {
-            registerKeyList[j - low] = m_keysA[j - low];
-          }
-          else
-          {
-            FwkInfo("DoRegisterInterestList() key[{0}] is null.", (j - low));
-          }
-        }
-        bool isDurable = GetBoolValue("isDurableReg");
-        ResetKey("getInitialValues"); 
-        bool isGetInitialValues = GetBoolValue("getInitialValues");
-        bool isReceiveValues = true;
-        bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-        if (checkReceiveVal)
-        {
-          ResetKey("receiveValue");
-          isReceiveValues = GetBoolValue("receiveValue");
-        }
-        region.GetSubscriptionService().RegisterKeys(registerKeyList, isDurable, isGetInitialValues, isReceiveValues);
-        String durableClientId = CacheHelper<TKey, TVal>.DCache.SystemProperties.DurableClientId;
-        if (durableClientId.Length > 0)
-        {
-          CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRegisterInterestList() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRegisterInterestList() complete.");
-    }
-
-    public void DoRegisterAllKeys()
-    {
-      FwkInfo("In DoRegisterAllKeys()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        FwkInfo("DoRegisterAllKeys() region name is {0}", region.Name);
-        bool isDurable = GetBoolValue("isDurableReg");
-        ResetKey("getInitialValues");
-        bool isGetInitialValues = GetBoolValue("getInitialValues");
-        bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-        bool isReceiveValues = true;
-        if (checkReceiveVal)
-        {
-          ResetKey("receiveValue");
-          isReceiveValues = GetBoolValue("receiveValue");
-        }
-        region.GetSubscriptionService().RegisterAllKeys(isDurable, isGetInitialValues,isReceiveValues);
-        String durableClientId = CacheHelper<TKey, TVal>.DCache.SystemProperties.DurableClientId;
-        if (durableClientId.Length > 0)
-        {
-          CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRegisterAllKeys() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRegisterAllKeys() complete.");
-    }
-
-    public void DoVerifyInterestList()
-    {
-      FwkInfo("In DoVerifyInterestList()");
-      try
-      {
-        int countUpdate = 0;
-        IRegion<TKey,TVal> region = GetRegion();
-        InitKeys();
-        ResetKey(RegisterKeys);
-        int numOfRegisterKeys = GetUIntValue(RegisterKeys);
-        int payload = GetUIntValue(ValueSizes);
-
-        
-        ICollection<TKey> keys = region.GetLocalView().Keys;
-
-        byte[] value;
-        int valueSize;
-        if (keys != null)
-        {
-          foreach (TKey key in keys)
-          {
-             bool containsValue = region.ContainsValueForKey(key);
-             RegionEntry<TKey,TVal> entry = region.GetEntry(key);
-             if(!containsValue)
-             {
-                FwkInfo("Skipping check for key {0}",key);
-             }
-             else
-             {
-               if (entry == null)
-               {
-                 FwkException("Failed to find entry for key [{0}] in local cache", key);
-               }
-               value = entry.Value as byte[];
-               if (value == null)
-               {
-                 FwkException("Failed to find value for key [{0}] in local cache", key);
-               }
-               valueSize = (value == null ? -1 : value.Length);
-               if (valueSize == payload)
-               {
-                 ++countUpdate;
-               }
-             }   
-             GC.KeepAlive(entry);
-          }
-        }
-        if (countUpdate != numOfRegisterKeys)
-        {
-          FwkException("DoVerifyInterestList() update interest list " +
-            "count {0} is not equal to number of register keys {1}",
-            countUpdate, numOfRegisterKeys);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoVerifyInterestList() Caught Exception: {0} : {1}",ex.GetType().Name, ex);
-      }
-      FwkInfo("DoVerifyInterestList() complete.");
-    }
-
-    public void DoRegisterRegexList()
-    {
-      FwkInfo("In DoRegisterRegexList()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        string regex = GetStringValue(RegisterRegex);
-        FwkInfo("DoRegisterRegexList() region name is {0}; regex is {1}",
-          region.Name, regex);
-        bool isDurable = GetBoolValue("isDurableReg");
-        ResetKey("getInitialValues");
-        bool isGetInitialValues = GetBoolValue("getInitialValues");
-        bool isReceiveValues = true;
-        bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-        if (checkReceiveVal)
-        {
-          ResetKey("receiveValue");
-          isReceiveValues = GetBoolValue("receiveValue");
-        }
-        region.GetSubscriptionService().RegisterRegex(regex, isDurable, isGetInitialValues, isReceiveValues);
-        String durableClientId = CacheHelper<TKey, TVal>.DCache.SystemProperties.DurableClientId;
-        if (durableClientId.Length > 0)
-        {
-          CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRegisterRegexList() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRegisterRegexList() complete.");
-    }
-
-    public void DoUnRegisterRegexList()
-    {
-      FwkInfo("In DoUnRegisterRegexList()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        string regex = GetStringValue(UnregisterRegex);
-        FwkInfo("DoUnRegisterRegexList() region name is {0}; regex is {1}",
-          region.Name, regex);
-        region.GetSubscriptionService().UnregisterRegex(regex);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoUnRegisterRegexList() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoUnRegisterRegexList() complete.");
-    }
-
-    public void DoDestroysKeys()
-    {
-      FwkInfo("In PerfTest::DoDestroyKeys()");
-      try
-      {
-        IRegion<TKey,TVal> region=GetRegion();
-        ResetKey("distinctKeys");
-        InitValues(InitKeys());
-        DestroyTask<TKey, TVal> destroys = new DestroyTask<TKey, TVal>(region, m_keysA);
-        RunTask(destroys,1,m_maxKeys,-1,-1,null);
-      }
-      catch(Exception e)
-      {
-        FwkException("PerfTest caught exception: {0}", e);
-      }
-      FwkInfo("In PerfTest::DoDestroyKeys()complete");
-    }
-
-    public void DoServerKeys()
-    {
-      FwkInfo("In DoServerKeys()");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        FwkAssert(region != null,
-          "DoServerKeys() No region to perform operations on.");
-        FwkInfo("DoServerKeys() region name is {0}", region.Name);
-
-        int expectedKeys = GetUIntValue(ExpectedCount);
-        ICollection<TKey> serverKeys = region.Keys;
-        int foundKeys = (serverKeys == null ? 0 : serverKeys.Count);
-        FwkAssert(expectedKeys == foundKeys,
-          "DoServerKeys() expected {0} keys but found {1} keys.",
-          expectedKeys, foundKeys);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoServerKeys() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoServerKeys() complete.");
-    }
-
-    public void DoIterateInt32Keys() 
-    {
-      FwkInfo("DoIterateInt32Keys() called.");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        FwkAssert(region != null,
-          "DoIterateInt32Keys() No region to perform operations on.");
-        FwkInfo("DoIterateInt32Keys() region name is {0}", region.Name);
-
-        ICollection<TKey> serverKeys = region.Keys;
-        FwkInfo("DoIterateInt32Keys() GetServerKeys() returned {0} keys.",
-          (serverKeys != null ? serverKeys.Count : 0));
-
-        if (serverKeys != null)
-        {
-          foreach (TKey intKey in serverKeys)
-          {
-            FwkInfo("ServerKeys: {0}", intKey);
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoIterateInt32Keys() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoIterateInt32Keys() complete.");
-    }
-    public void DoValidateQConflation()
-    {
-      FwkInfo("DoValidateQConflation() called.");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        region.GetLocalView().DestroyRegion();
-        int expectedAfterCreateEvent = GetUIntValue("expectedAfterCreateCount");
-        int expectedAfterUpdateEvent = GetUIntValue("expectedAfterUpdateCount");
-        bool isServerConflateTrue = GetBoolValue("isServerConflateTrue");
-        Int32 eventAfterCreate = (Int32)Util.BBGet("ConflationCacheListener", "AFTER_CREATE_COUNT_" + Util.ClientId + "_" + region.Name);
-        Int32 eventAfterUpdate = (Int32)Util.BBGet("ConflationCacheListener", "AFTER_UPDATE_COUNT_" + Util.ClientId + "_" + region.Name);
-        
-        FwkInfo("DoValidateQConflation() -- eventAfterCreate {0} and eventAfterUpdate {1}", eventAfterCreate, eventAfterUpdate);
-        String conflateEvent = CacheHelper<TKey, TVal>.DCache.SystemProperties.ConflateEvents;
-        String durableClientId = CacheHelper<TKey, TVal>.DCache.SystemProperties.DurableClientId;
-        Int32 totalCount = 3500;
-        if(durableClientId.Length > 0) {
-          FwkInfo("DoValidateQConflation() Validation for Durable client .");
-          if (conflateEvent.Equals("true") && ((eventAfterCreate + eventAfterUpdate) < totalCount +10))
-          {  
-            FwkInfo("DoValidateQConflation() Conflate Events is true complete.");
-          }
-          else if (conflateEvent.Equals("false") && ((eventAfterCreate + eventAfterUpdate) == totalCount +10))
-          {
-            FwkInfo("DoValidateQConflation() Conflate Events is false complete.");
-          }
-          else if (conflateEvent.Equals("server") && isServerConflateTrue && ((eventAfterCreate + eventAfterUpdate) <= totalCount + 10))
-          {
-            FwkInfo("DoValidateQConflation() Conflate Events is server=true complete.");
-          }
-          else if (conflateEvent.Equals("server") && !isServerConflateTrue && ((eventAfterCreate + eventAfterUpdate) == totalCount + 10))
-          {
-            FwkInfo("DoValidateQConflation() Conflate Events is server=false complete.");
-          }
-          else
-          {
-            FwkException("DoValidateQConflation() ConflateEvent setting is {0} and Expected AfterCreateCount to have {1} keys and " +
-               " found {2} . Expected AfterUpdateCount to have {3} keys, found {4} keys", conflateEvent, expectedAfterCreateEvent
-             , eventAfterCreate, expectedAfterUpdateEvent, eventAfterUpdate);
-          }
-        }
-        else {
-          if (conflateEvent.Equals("true") && ((eventAfterCreate == expectedAfterCreateEvent) &&
-            (((eventAfterUpdate >= expectedAfterUpdateEvent)) && eventAfterUpdate < totalCount)))
-          {
-            FwkInfo("DoValidateQConflation() Conflate Events is true complete.");
-          }
-          else if (conflateEvent.Equals("false") && ((eventAfterCreate == expectedAfterCreateEvent) &&
-            (eventAfterUpdate == expectedAfterUpdateEvent)))
-          {
-            FwkInfo("DoValidateQConflation() Conflate Events is false complete.");
-          }
-          else if (conflateEvent.Equals("server") && isServerConflateTrue && ((eventAfterCreate == expectedAfterCreateEvent) &&
-            (((eventAfterUpdate >= expectedAfterUpdateEvent)) && eventAfterUpdate < totalCount)))
-          {
-            FwkInfo("DoValidateQConflation() Conflate Events is server=true complete.");
-          }
-          else if (conflateEvent.Equals("server") && !isServerConflateTrue && ((eventAfterCreate == expectedAfterCreateEvent) &&
-            (eventAfterUpdate == expectedAfterUpdateEvent)))
-          {
-            FwkInfo("DoValidateQConflation() Conflate Events is server=false complete.");
-          }
-          else
-          {
-            FwkException("DoValidateQConflation() ConflateEvent setting is {0} and Expected AfterCreateCount to have {1} keys and " +
-               " found {2} . Expected AfterUpdateCount to have {3} keys, found {4} keys" , conflateEvent,expectedAfterCreateEvent
-             , eventAfterCreate,expectedAfterUpdateEvent, eventAfterUpdate);
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoValidateQConflation() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoValidateQConflation() complete.");
-    }
-
-    public void DoCreateUpdateDestroy()
-    {
-      FwkInfo("DoCreateUpdateDestroy() called.");
-      try
-      {
-        DoPopulateRegion();
-        DoPopulateRegion();
-        DoDestroysKeys();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreateUpdateDestroy() Caught Exception: {0}", ex);
-      }
-        FwkInfo("DoCreateUpdateDestroy() complete.");
-    }
-
-    public void DoValidateBankTest()
-    {
-      FwkInfo("DoValidateBankTest() called.");
-      try
-      {
-        IRegion<TKey,TVal> region = GetRegion();
-        region.GetLocalView().DestroyRegion();
-        int expectedAfterCreateEvent = GetUIntValue("expectedAfterCreateCount");
-        int expectedAfterUpdateEvent = GetUIntValue("expectedAfterUpdateCount");
-        int expectedAfterInvalidateEvent = GetUIntValue("expectedAfterInvalidateCount");
-        int expectedAfterDestroyEvent = GetUIntValue("expectedAfterDestroyCount");
-        Int32 eventAfterCreate = (Int32)Util.BBGet("ConflationCacheListener", "AFTER_CREATE_COUNT_" + Util.ClientId + "_" + region.Name);
-        Int32 eventAfterUpdate = (Int32)Util.BBGet("ConflationCacheListener", "AFTER_UPDATE_COUNT_" + Util.ClientId + "_" + region.Name);
-        Int32 eventAfterInvalidate = (Int32)Util.BBGet("ConflationCacheListener", "AFTER_INVALIDATE_COUNT_" + Util.ClientId + "_" + region.Name);
-        Int32 eventAfterDestroy = (Int32)Util.BBGet("ConflationCacheListener", "AFTER_DESTROY_COUNT_" + Util.ClientId + "_" + region.Name);
-
-
-        FwkInfo("DoValidateBankTest() -- eventAfterCreate {0} ,eventAfterUpdate {1} ," +
-          "eventAfterInvalidate {2} , eventAfterDestroy {3}", eventAfterCreate, eventAfterUpdate,eventAfterInvalidate,eventAfterDestroy);
-
-        if (expectedAfterCreateEvent == eventAfterCreate && expectedAfterUpdateEvent == eventAfterUpdate &&
-           expectedAfterInvalidateEvent == eventAfterInvalidate && expectedAfterDestroyEvent == eventAfterDestroy)
-        {
-          FwkInfo("DoValidateBankTest() Validation success.");
-        }
-        else
-        {
-          FwkException("Validation Failed() Region: {0} eventAfterCreate {1}, eventAfterUpdate {2} " +
-             "eventAfterInvalidate {3}, eventAfterDestroy {4}  ",region.Name, eventAfterCreate, eventAfterUpdate
-             , eventAfterInvalidate, eventAfterDestroy);
-        }
-              
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoValidateBankTest() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoValidateBankTest() complete.");
-    }
-    #endregion 
-  }
-}
diff --git a/tests/cli/NewFwkLib/QueryTest/QueryTests.cs b/tests/cli/NewFwkLib/QueryTest/QueryTests.cs
deleted file mode 100644
index 99380d4..0000000
--- a/tests/cli/NewFwkLib/QueryTest/QueryTests.cs
+++ /dev/null
@@ -1,1936 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using Apache.Geode.Client.Tests; // for Portfolio and Position classes
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-  using QueryCategory = Apache.Geode.Client.Tests.QueryCategory;
-  using QueryStrings = Apache.Geode.Client.Tests.QueryStrings;
-  using QueryStatics = Apache.Geode.Client.Tests.QueryStatics;
-  using System.Threading;
-  using System.Xml.Serialization;
-  using System.IO;
-  using System.Reflection;
-
-  public class MyCq1Listener<TKey, TResult> : ICqListener<TKey, TResult>
-  {
-    private UInt32 m_updateCnt;
-    private UInt32 m_createCnt;
-    private UInt32 m_destroyCnt;
-    private UInt32 m_eventCnt;
-    
-    public MyCq1Listener()
-    {
-      m_updateCnt = 0;
-      m_createCnt = 0;
-      m_destroyCnt = 0;
-      m_eventCnt = 0;
-    }
-
-    public UInt32 NumInserts()
-    {
-      return m_createCnt;
-    }
-
-    public UInt32 NumUpdates()
-    {
-      return m_updateCnt;
-    }
-
-    public UInt32 NumDestroys()
-    {
-      return m_destroyCnt;
-    }
-
-    public UInt32 NumEvents()
-    {
-      return m_eventCnt;
-    }
-
-    public virtual void UpdateCount(CqEvent<TKey, TResult> ev)
-    {
-      m_eventCnt++;
-      CqOperation opType = ev.getQueryOperation();
-      if (opType == CqOperation.OP_TYPE_CREATE)
-      {
-          Util.Log("ML:INSERT invoked");
-        m_createCnt++;
-      }
-      else if (opType == CqOperation.OP_TYPE_UPDATE)
-      {
-          Util.Log("ML:UPDATE invoked");
-        m_updateCnt++;
-      }
-      else if (opType == CqOperation.OP_TYPE_DESTROY)
-      {
-          Util.Log("ML:DESTROY invoked");
-        m_destroyCnt++;
-      }
- 
-    }
-    public virtual void OnError(CqEvent<TKey, TResult> ev)
-    {
-      UpdateCount(ev);
-    }
-
-    public virtual void OnEvent(CqEvent<TKey, TResult> ev)
-    {
-      UpdateCount(ev);
-    }
-
-    public virtual void Close()
-    { 
-    }
-
-  }
-
-  public class QueryTests<TKey, TVal> : FwkTest<TKey, TVal>
-   {
-    public QueryTests()
-      : base()
-    {
-    }
-
-    #region Private constants
-
-    private static TimeSpan QueryResponseTimeout = TimeSpan.FromSeconds(600);
-    
-    private const string QueryBB = "QueryBB";
-    private const string DistinctKeys = "distinctKeys";
-    private const string DestroyKeys = "destroyKeys";
-    private const string InvalidateKeys = "invalidateKeys";
-    private const string ObjectType = "objectType";
-    private const string NumThreads = "numThreads";
-    private const string ValueSizes = "valueSizes";
-    private const string QueryString = "query";
-    private const string QueryResultType = "queryResultType";
-    private const string CategoryType = "categoryType";
-    private const string ResultSize = "resultSize";
-    private const string RegionPaths = "regionPaths";
-    private const string RegionName = "regionName";
-    private const string LargeSetQuery = "largeSetQuery";
-    private const string IsDurable = "isDurable";
-    private const string WorkTime = "workTime";
-    private const string RegisterAndExecuteCq = "registerAndExecuteCQs";
-    private const string CqState = "cqState";
-    private static Cache m_cache = null;
-    private static bool isObjectRegistered = false;
-    private static bool m_istransaction = false;
-    private CacheTransactionManager txManager = null;
-   
-    #endregion
-
-    #region Private utility methods
-
-    private string GetNextRegionName(ref IRegion<TKey, TVal> region)
-    {
-      string regionName = string.Empty;
-      int count = 0;
-      string path = string.Empty;
-
-      do
-      {
-        path = GetStringValue(RegionPaths);
-
-        if (path == null || path.Length <= 0)
-        {
-          return path;
-        }
-
-        FwkInfo("QueryTestGetNextRegionName() RegionPath is " + path);
-        do
-        {
-          int length = path.Length;
-
-          try
-          {
-            region = (IRegion<TKey, TVal>)CacheHelper<TKey, TVal>.DCache.GetRegion<TKey, TVal>(path);
-          }
-          catch (Exception)
-          {
-          }
-
-          if (region == null)
-          {
-            int pos = path.LastIndexOf('/');
-            regionName = path.Substring(pos+1);
-            path = path.Substring(0, pos);
-          }
-        }
-        while (region == null && path.Length > 0);
-      }
-      while ((++count < 5) && regionName.Length <= 0);
-
-      return regionName;
-    }
-
-    protected IRegion<TKey, TVal> GetRegion()
-    {
-      return GetRegion(null);
-    }
-
-    protected IRegion<TKey, TVal> GetRegion(string regionName)
-    {
-      IRegion<TKey, TVal> region;
-      if (regionName == null)
-      {
-        region = GetRootRegion();
-      }
-      else
-      {
-        region = CacheHelper<TKey, TVal>.GetRegion(regionName);
-      }
-      return region;
-    }
-
-    private bool VerifyResultSet()
-    {
-      return VerifyResultSet(0);
-    }
-
-    private bool VerifyResultSet(int distinctKeys)
-    {
-      bool result = false;
-      int numOfKeys;
-      if (distinctKeys > 0)
-      {
-        numOfKeys = distinctKeys;
-      }
-      else
-      {
-        ResetKey(DistinctKeys);
-        numOfKeys = GetUIntValue(DistinctKeys);
-      }
-      QueryHelper<TKey,TVal> qh = QueryHelper<TKey,TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-      int setSize = qh.PortfolioSetSize;
-      FwkInfo("QueryTests.VerifyResultSet: numOfKeys [{0}], setSize [{1}].",
-        numOfKeys, setSize);
-      if (numOfKeys < setSize)
-      {
-        setSize = numOfKeys;
-      }
-      int numSet = numOfKeys / setSize;
-
-      var qs = CheckQueryService();
-
-      ResetKey(CategoryType);
-      int category;
-
-      ResetKey(LargeSetQuery);
-      bool isLargeSetQuery = bool.Parse(GetStringValue(LargeSetQuery));
-      ResetKey("cq");
-      bool isCq = GetBoolValue("cq");
-      ResetKey("paramquery");
-      bool isParamquery = GetBoolValue("paramquery");
-      int RSsize = 0;
-      if (isCq)
-        RSsize = QueryStrings.CQRSsize;
-      else if(isParamquery)
-        RSsize = QueryStrings.RSPsize;
-      else
-        RSsize = QueryStrings.RSsize;
-      while ((category = GetUIntValue(CategoryType)) > 0)
-      {
-        for (int index = 0; index < RSsize; index++)
-        {
-          
-          try
-          {
-            if (isCq)
-            {
-              if ((int)QueryStatics.CqResultSetQueries[index].Category == category - 1 &&
-                QueryStatics.CqResultSetQueries[index].Category != QueryCategory.Unsupported &&
-                QueryStatics.CqResultSetQueries[index].IsLargeResultset == isLargeSetQuery)
-              {
-                string CqQuery = QueryStatics.CqResultSetQueries[index].Query;
-                FwkInfo("QueryTests.VerifyResultSet: Query Category [{0}]," +
-              " CqQueryString [{1}], NumSet [{2}].", category - 1, CqQuery, numSet);
-
-                ISelectResults<object> results = ContinuousQuery(qs, QueryStatics.CqResultSetQueries[index].Query, index);
-
-                if ((category - 1 != (int)QueryCategory.Unsupported) 
-                  && (!qh.VerifyRS(results, qh.IsExpectedRowsConstantCQRS(index) ?
-                   QueryStatics.CqResultSetRowCounts[index] :
-                   QueryStatics.CqResultSetRowCounts[index] * numSet)))
-                {
-                  FwkSevere("QueryTests.VerifyStructSet: Query verify failed" +
-                    " for query index {0}", index);
-                  return false;
-                }
-                else
-                {
-                  result = true;
-                }
-              }
-            }
-            else if (isParamquery)
-            {
-              if ((int)QueryStatics.ResultSetParamQueries[index].Category == category - 1 &&
-                QueryStatics.ResultSetParamQueries[index].Category != QueryCategory.Unsupported &&
-                QueryStatics.ResultSetParamQueries[index].IsLargeResultset == isLargeSetQuery)
-              {
-                string query = QueryStatics.ResultSetParamQueries[index].Query;
-                FwkInfo("QueryTests.VerifyResultSet: Query Category [{0}]," +
-                " QueryString [{1}], NumSet [{2}].", category - 1, query, numSet);
-                //ISerializable[] paramList = new ISerializable[QueryStatics.NoOfQueryParam[index]];
-                object[] paramList = new object[QueryStatics.NoOfQueryParam[index]];
-                Int32 numVal = 0;
-                for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParam[index]; ind++)
-                {
-                  try
-                  {
-                    numVal = Convert.ToInt32(QueryStatics.QueryParamSet[index][ind]);
-                    //paramList[ind] = new CacheableInt32(numVal);
-                    paramList[ind] = numVal;
-                  }
-                  catch (FormatException)
-                  {
-                    paramList[ind] = (System.String)QueryStatics.QueryParamSet[index][ind];
-                  }
-                }
-                Query<object> qry = qs.NewQuery<object>(query);
-                DateTime startTime;
-                DateTime endTime;
-                TimeSpan elapsedTime;
-                startTime = DateTime.Now;
-                ISelectResults<object> results = qry.Execute(paramList, QueryResponseTimeout);
-                endTime = DateTime.Now;
-                elapsedTime = endTime - startTime;
-                FwkInfo("QueryTests.VerifyResultSet: Time Taken to execute" +
-                  " the query [{0}]: {1}ms", query,
-                  elapsedTime.TotalMilliseconds);
-
-                FwkInfo("QueryTests.VerifyResultSet: ResultSet size [{0}]," +
-                  " numSet [{1}], setRowCount [{2}]", results.Size, numSet,
-                  QueryStatics.ResultSetRowCounts[index]);
-                if ((category - 1 != (int)QueryCategory.Unsupported) &&
-                  (!qh.VerifyRS(results, qh.IsExpectedRowsConstantPQRS(index) ?
-                  QueryStatics.ResultSetPQRowCounts[index] :
-                  QueryStatics.ResultSetPQRowCounts[index] * numSet)))
-                {
-                  FwkSevere("QueryTests.VerifyStructSet: Param Query verify failed" +
-                    " for query index {0}", index);
-                  return false;
-                }
-                else
-                {
-                  result = true;
-                }
-              }
-            }
-            else
-            {
-              if ((int)QueryStatics.ResultSetQueries[index].Category == category - 1 &&
-                QueryStatics.ResultSetQueries[index].Category != QueryCategory.Unsupported &&
-                QueryStatics.ResultSetQueries[index].IsLargeResultset == isLargeSetQuery)
-              {
-                string query = QueryStatics.ResultSetQueries[index].Query;
-                FwkInfo("QueryTests.VerifyResultSet: Query Category [{0}]," +
-                " QueryString [{1}], NumSet [{2}].", category - 1, query, numSet);
-
-                ISelectResults<object> results = RemoteQuery(qs, QueryStatics.ResultSetQueries[index].Query);
-
-                FwkInfo("QueryTests.VerifyResultSet: ResultSet size [{0}]," +
-                  " numSet [{1}], setRowCount [{2}]", results.Size, numSet,
-                  QueryStatics.ResultSetRowCounts[index]);
-                if ((category - 1 != (int)QueryCategory.Unsupported) &&
-                  (!qh.VerifyRS(results, qh.IsExpectedRowsConstantRS(index) ?
-                  QueryStatics.ResultSetRowCounts[index] :
-                  QueryStatics.ResultSetRowCounts[index] * numSet)))
-                {
-                  FwkSevere("QueryTests.VerifyResultSet: Query verify failed" +
-                    " for query index {0}", index);
-                  return false;
-                }
-                else
-                {
-                  result = true;
-                }
-              }
-            }
-          }
-          catch (Exception)
-          {
-            if (category - 1 != (int)QueryCategory.Unsupported)
-            {
-              throw;
-            }
-          }
-        }
-        category = GetUIntValue("categoryType");
-        GC.Collect();
-        GC.WaitForPendingFinalizers();
-      }
-      return result;
-    }
-   
-    private bool VerifyStructSet()
-    {
-      return VerifyStructSet(0);
-    }
-
-    private bool VerifyStructSet(int distinctKeys)
-    {
-      bool result = false;
-      int numOfKeys;
-      if (distinctKeys > 0)
-      {
-        numOfKeys = distinctKeys;
-      }
-      else
-      {
-        ResetKey(DistinctKeys);
-        numOfKeys = GetUIntValue(DistinctKeys);
-      }
-      QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-      int setSize = qh.PortfolioSetSize;
-      FwkInfo("QueryTests.VerifyStructSet: numOfKeys [{0}], setSize [{1}].",
-        numOfKeys, setSize);
-      if (numOfKeys < setSize)
-      {
-        setSize = numOfKeys;
-      }
-      int numSet = numOfKeys / setSize;
-
-      var qs = CheckQueryService();
-
-      DateTime startTime;
-      DateTime endTime;
-      TimeSpan elapsedTime;
-      ResetKey(CategoryType);
-      int category;
-      string objectType = GetStringValue(ObjectType);
-      ResetKey(LargeSetQuery);
-      bool isLargeSetQuery = bool.Parse(GetStringValue(LargeSetQuery));
-      ResetKey( "paramquery" );
-      bool isParamquery = GetBoolValue( "paramquery" );
-      int SSsize = 0;
-      if(isParamquery)
-        SSsize = QueryStrings.SSPsize;
-      else
-        SSsize = QueryStrings.SSsize;
-      while ((category = GetUIntValue(CategoryType)) > 0)
-      {
-        for (int index = 0; index < SSsize; index++)
-        {
-          if(isParamquery) {
-          if ((int)QueryStatics.StructSetParamQueries[index].Category == category - 1 &&
-            QueryStatics.StructSetParamQueries[index].Category != QueryCategory.Unsupported &&
-            QueryStatics.StructSetParamQueries[index].IsLargeResultset == isLargeSetQuery)
-          {
-            string query = QueryStatics.StructSetParamQueries[index].Query;
-            FwkInfo("QueryTests.VerifyStructSet: Query Category [{0}]," +
-              " String [{1}], NumSet [{2}].", category - 1, query, numSet);
-            try
-            {
-              Query<object> qry = qs.NewQuery<object>(query);
-              object[] paramList = new object[QueryStatics.NoOfQueryParamSS[index]];
-
-              Int32 numVal = 0;
-              for (Int32 ind = 0; ind < QueryStatics.NoOfQueryParamSS[index]; ind++)
-              {
-                try
-                {
-                  numVal = Convert.ToInt32(QueryStatics.QueryParamSetSS[index][ind]);
-                  paramList[ind] = numVal;
-               }
-                catch (FormatException )
-                {
-                  paramList[ind] = (System.String)QueryStatics.QueryParamSetSS[index][ind];
-                }
-              }
-              startTime = DateTime.Now;
-              ISelectResults<object> results = qry.Execute(paramList, QueryResponseTimeout);
-              endTime = DateTime.Now;
-              elapsedTime = endTime - startTime;
-              FwkInfo("QueryTests.VerifyStructSet: Time Taken to execute" +
-                " the query [{0}]: {1}ms", query,
-                elapsedTime.TotalMilliseconds);
-              FwkInfo("QueryTests.VerifyStructSet: StructSet size [{0}]," +
-                " numSet [{1}], setRowCount [{2}]", results.Size, numSet,
-                QueryStatics.StructSetPQRowCounts[index]);
-              if ((category - 1 != (int)QueryCategory.Unsupported) &&
-                (!qh.VerifySS(results, qh.IsExpectedRowsConstantPQSS(index) ?
-                QueryStatics.StructSetPQRowCounts[index] :
-                QueryStatics.StructSetPQRowCounts[index] * numSet,
-                QueryStatics.StructSetPQFieldCounts[index])))
-              {
-                FwkSevere("QueryTests.VerifyStructSet: Param Query verify failed" +
-                  " for query index {0}", index);
-                return false;
-              }
-              else
-              {
-                result = true;
-              }
-            }
-            catch
-            {
-              if (category - 1 != (int)QueryCategory.Unsupported)
-              {
-                throw;
-              }
-            }
-          }//}
-        }
-          else {
-          if ((int)QueryStatics.StructSetQueries[index].Category == category-1 &&
-            QueryStatics.StructSetQueries[index].Category != QueryCategory.Unsupported &&
-            QueryStatics.StructSetQueries[index].IsLargeResultset == isLargeSetQuery)
-          {
-            int [] a = new int[] {4,6,7,9,12,14,15,16};
-            if ((typeof(TVal).Equals(typeof(Apache.Geode.Client.Tests.PortfolioPdx))||
-              (typeof(TVal).Equals(typeof(Apache.Geode.Client.Tests.PositionPdx)))) && ((IList<int>)a).Contains(index))
-            {
-              FwkInfo("Skiping Query for pdx object [{0}]", QueryStatics.StructSetQueries[index].Query);
-            }
-            else {
-            string query = QueryStatics.StructSetQueries[index].Query;
-            FwkInfo("QueryTests.VerifyStructSet: Query Category [{0}]," +
-              " String [{1}], NumSet [{2}].", category-1, query, numSet);
-            try
-            {
-              Query<object> qry = qs.NewQuery<object>(query);
-              startTime = DateTime.Now;
-              ISelectResults<object> results = qry.Execute(QueryResponseTimeout);
-              endTime = DateTime.Now;
-              elapsedTime = endTime - startTime;
-              FwkInfo("QueryTests.VerifyStructSet: Time Taken to execute" +
-                " the query [{0}]: {1}ms", query,
-                elapsedTime.TotalMilliseconds);
-              FwkInfo("QueryTests.VerifyStructSet: StructSet size [{0}]," +
-                " numSet [{1}], setRowCount [{2}]", results.Size, numSet,
-                QueryStatics.StructSetRowCounts[index]);
-              if ((category-1 != (int)QueryCategory.Unsupported) &&
-                (!qh.VerifySS(results, qh.IsExpectedRowsConstantSS(index) ?
-                QueryStatics.StructSetRowCounts[index] :
-                QueryStatics.StructSetRowCounts[index] * numSet,
-                QueryStatics.StructSetFieldCounts[index])))
-              {
-                FwkSevere("QueryTests.VerifyStructSet: Query verify failed" +
-                  " for query index {0}", index);
-                return false;
-              }
-              else
-              {
-                result = true;
-              }
-            }
-            catch
-            {
-              if (category - 1 != (int)QueryCategory.Unsupported)
-              {
-                throw;
-              }
-            }
-           }
-          }
-        }
-          GC.Collect();
-          GC.WaitForPendingFinalizers();
-        }
-      }
-      return result;
-    }
-
-    private bool ReadQueryString(ref String query)
-    {
-      bool isCq = GetBoolValue("cq");
-      do
-      {
-        var resultSize = (ulong) GetUIntValue(ResultSize);  // set the query result size in xml
-        FwkInfo("ReadQueryString: Query String is: {0}, resultSize: {1}",
-          query, resultSize);
-        if (resultSize < 0)
-        {
-          FwkSevere("ReadQueryString: ResultSize is not defined in xml.");
-          return false;
-        }
-        var qs = CheckQueryService();
-        DateTime startTime;
-        TimeSpan elapsedTime;
-        ISelectResults<object> results;
-        if (isCq)
-        {
-          string CqName = String.Format("_default{0}",query);
-          CqQuery<TKey, object> cq = qs.GetCq<TKey, object>(CqName);
-          startTime = DateTime.Now;
-          results = cq.ExecuteWithInitialResults(QueryResponseTimeout);
-          elapsedTime = DateTime.Now - startTime;
-          FwkInfo("ReadQueryString: Time Taken to execute the CqQuery [{0}]:" +
-          "{1}ms ResultSize Size = {2}", query, elapsedTime.TotalMilliseconds ,results.Size);
-        }
-        else
-        {
-          startTime = DateTime.Now;
-          Query<object> qry = qs.NewQuery<object>(query);
-          results = qry.Execute(QueryResponseTimeout);
-          elapsedTime = DateTime.Now - startTime;
-          FwkInfo("ReadQueryString: Time Taken to execute the query [{0}]:" +
-            "{1}ms", query, elapsedTime.TotalMilliseconds);
-        }
-        if (resultSize != results.Size)
-        {
-          FwkSevere("ReadQueryString: Result size found {0}, expected {1}.",
-            results.Size, resultSize);
-          return false;
-        }
-        FwkInfo("ReadQueryString: Got expected result size {0}.",
-          results.Size);
-      } while ((query = GetStringValue(QueryString)) != null &&
-        query.Length > 0);
-      return true;
-    }
-
-    #endregion
-
-    #region Public methods
-    public void DoCreateDCRegion()
-    {
-      FwkInfo("In DoCreateDCRegion() Durable");
-
-      ClearCachedKeys();
-
-      string rootRegionData = GetStringValue("regionSpec");
-      string tagName = GetStringValue("TAG");
-      string endpoints = Util.BBGet(JavaServerBB, EndPointTag + tagName)
-        as string;
-      if (rootRegionData != null && rootRegionData.Length > 0)
-      {
-        string rootRegionName;
-        rootRegionName = GetRegionName(rootRegionData);
-        if (rootRegionName != null && rootRegionName.Length > 0)
-        {
-          IRegion<TKey, TVal> region;
-          if ((region = CacheHelper<TKey, TVal>.GetRegion(rootRegionName)) == null)
-          {
-            bool isDC = GetBoolValue("isDurable");
-            RegionFactory rootAttrs = null;
-            string m_isPool = null;
-            // Check if this is a thin-client region; if so set the endpoints
-            int redundancyLevel = 0;
-            if (endpoints != null && endpoints.Length > 0)
-            {
-              redundancyLevel = GetUIntValue(RedundancyLevelKey);
-              if (redundancyLevel < 0)
-                redundancyLevel = 0;
-              string conflateEvents = GetStringValue(ConflateEventsKey);
-              string durableClientId = "";
-              int durableTimeout = 300;
-              if (isDC)
-              {
-                durableTimeout = GetUIntValue("durableTimeout");
-                bool isFeeder = GetBoolValue("isFeeder");
-                if (isFeeder)
-                {
-                  durableClientId = "Feeder";
-                  // VJR: Setting FeederKey because listener cannot read boolean isFeeder
-                  // FeederKey is used later on by Verify task to identify feeder's key in BB
-                  Util.BBSet("DURABLEBB", "FeederKey", "ClientName_" + Util.ClientNum + "_Count");
-                }
-                else
-                {
-                  durableClientId = String.Format("ClientName_{0}", Util.ClientNum);
-                }
-              }
-              FwkInfo("DurableClientID is {0} and DurableTimeout is {1}", durableClientId, durableTimeout);
-              ResetKey("sslEnable");
-              bool isSslEnable = GetBoolValue("sslEnable");
-              CacheHelper<TKey, TVal>.InitConfigForPoolDurable(durableClientId, durableTimeout, conflateEvents, isSslEnable);
-              rootAttrs = CacheHelper<TKey, TVal>.DCache.CreateRegionFactory(RegionShortcut.PROXY);
-              SetRegionAttributes(rootAttrs, rootRegionData, ref m_isPool);
-            }
-            rootAttrs = CreatePool(rootAttrs, redundancyLevel);
-            region = CacheHelper<TKey, TVal>.CreateRegion(rootRegionName, rootAttrs);
-            Apache.Geode.Client.RegionAttributes<TKey, TVal> regAttr = region.Attributes;
-            FwkInfo("Region attributes for {0}: {1}", rootRegionName,
-              CacheHelper<TKey, TVal>.RegionAttributesToString(regAttr));
-            if (isDC)
-            {
-                CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-            }
-          }
-        }
-      }
-      else
-      {
-        FwkSevere("DoCreateDCRegion() failed to create region");
-      }
-
-      FwkInfo("DoCreateDCRegion() complete.");
-    }
-    public void DoCreateUserDefineRegion()
-    {
-      FwkInfo("In QueryTest.DoCreateUserDefineRegion()");
-      try
-      {
-          FwkInfo("isObjectRegistered value is {0}",isObjectRegistered);
-        if (!isObjectRegistered)
-        {
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterType(Portfolio.CreateDeserializable, 8);
-          FwkInfo("Completed Portfolio registeration");
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterType(Position.CreateDeserializable, 7);
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterPdxType(PortfolioPdx.CreateDeserializable);
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterPdxType(PositionPdx.CreateDeserializable);
-          FwkInfo("Completed other object registeration");
-          isObjectRegistered = true;
-        }
-        string regionName = GetStringValue(RegionName);
-        bool isDurable = GetBoolValue("isDurable");
-        if (isDurable)
-        {
-          DoCreateDCRegion();
-        }
-        else
-        {
-          IRegion<TKey, TVal> region = CreateRootRegion(regionName);
-
-          string key = region.Name;
-          Util.BBIncrement(QueryBB, key);
-
-          FwkInfo("QueryTest.DoCreateUserDefineRegion() Created Region " +
-            region.Name);
-        }
-        
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTest.DoCreateUserDefineRegion() Caught Exception: {0}", ex);
-      }
-    }
-    
-    public void DoRegisterCq()
-    {
-      FwkInfo("In Query.DoRegisterCq()");
-      try
-      {
-        int cqNum=0;
-        string qryStr = GetStringValue(QueryString);
-        string clientId = Util.ClientId;
-        string key = "CQLISTENER_" + clientId;
-        while (qryStr != null)
-        {
-          var qs = CheckQueryService();
-          CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-          ICqListener<TKey, object> cqLstner = new MyCq1Listener<TKey, object>();
-          cqFac.AddCqListener(cqLstner);
-          CqAttributes<TKey, object> cqAttr = cqFac.Create();
-          string CqName = String.Format("cq-{0}", cqNum++);
-          FwkInfo("Reading Query from xml {0} for cq {1}", qryStr, CqName);
-          CqQuery<TKey, object> qry = qs.NewCq(CqName, qryStr, cqAttr, false);
-          ISelectResults<object> results = qry.ExecuteWithInitialResults(QueryResponseTimeout);
-          Util.BBIncrement("CqListenerBB", key);
-        }
-      }
-      catch(Exception ex)
-      {
-        FwkException("Query.DoRegisterCq() Caught Exception: {0}", ex);
-      }
-    }
-
-    public void DoRegisterCqForConc()
-    {
-      FwkInfo("In Query.DoRegisterCqForConc()");
-      try
-      {
-        string qryStr = GetStringValue(QueryString);
-        string clientId = Util.ClientId;
-        string key = "CQLISTENER_" + clientId;
-        ResetKey("isDurableC");
-        bool isdurable = GetBoolValue("isDurableC");
-        while (qryStr != null)
-        {
-          var qs = CheckQueryService();
-          CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-          ICqListener<TKey, object> cqLstner = new MyCq1Listener<TKey, object>();
-          cqFac.AddCqListener(cqLstner);
-          CqAttributes<TKey, object> cqAttr = cqFac.Create();
-          CqQuery<TKey, object> qry=null ;
-          qry = qs.NewCq(qryStr, cqAttr, isdurable);
-          FwkInfo("Registered Cq {0} with query {1} and isDurable {2} ", qry.Name, qryStr, isdurable);
-          ResetKey(RegisterAndExecuteCq);
-          ResetKey("executeWithIR");
-          bool regAndExcCq = GetBoolValue(RegisterAndExecuteCq);
-          bool isExecuteWithIR = GetBoolValue("executeWithIR");
-          FwkInfo("Registered Cq with regAndExcCq {0} and with isExecuteWithIR {1} and with QueryState = {2} ", regAndExcCq, isExecuteWithIR, qry.GetState());
-          if (regAndExcCq)
-             qry.Execute();
-          if (isExecuteWithIR)
-              qry.ExecuteWithInitialResults(QueryResponseTimeout);
-          qryStr = GetStringValue(QueryString);
-          Util.BBIncrement("CqListenerBB", key);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("Query.DoRegisterCqForConc() Caught Exception: {0}", ex);
-      }
-    }
-
-    public void DoValidateCq()
-    {
-        FwkInfo("In QueryTest.DoValidateCq()");
-        try
-        {
-          var qs = CheckQueryService();
-          ResetKey("isDurableC");
-          bool isdurable = GetBoolValue("isDurableC");
-          ResetKey("NoCqs");
-          int numCqs = GetUIntValue("NoCqs");
-          
-          CqServiceStatistics cqSvcStats = qs.GetCqStatistics();
-          FwkInfo("Number of Cqs created is {0} number of Cqs active is {1} number of Cqs Closed is {2} number of Cqs onClient is {3} number of Cqs stopped is {4} ", cqSvcStats.numCqsCreated(), cqSvcStats.numCqsActive(), cqSvcStats.numCqsClosed(), cqSvcStats.numCqsOnClient(), cqSvcStats.numCqsStopped());
-          System.Collections.Generic.List<string> durableCqList = qs.GetAllDurableCqsFromServer();
-
-          int actualCqs = durableCqList.Count;
-          UInt32 expectedCqs = cqSvcStats.numCqsCreated() - cqSvcStats.numCqsClosed();
-
-          if (isdurable)
-          {
-              if (expectedCqs == actualCqs)
-               {
-                   FwkInfo("No of durableCqs on DC client is {0}  which is equal to the number of expected Cqs {1}", actualCqs, expectedCqs);
-               }
-             else
-                  FwkException("No of durableCqs on DC client is {0} is not equal to the number of expected Cqs {1} ", actualCqs, expectedCqs);
-          }
-          else
-          {
-              if (durableCqList.Count == 0)
-             {
-                FwkInfo("No. of durable Cqs for NDC is {0}", durableCqList.Count);
-             }
-             else
-               FwkException("Client is not durable, hence durableCqs for this client should have, had been 0,but it is{0}", durableCqList.Count);
-          }
-          FwkInfo("Cq durable list is {0}",durableCqList.Count);
-        }
-        catch (Exception ex)
-        {
-            FwkException("Query.DoValidateCq() Caught Exception : {0}", ex);
-        }
-    }
-
-    public void DoVerifyCQListenerInvoked()
-    {
-      FwkInfo("In QueryTest.DoVerifyCQListenerInvoked()");
-      try
-      {
-        var qs = CheckQueryService();
-        ICqListener<TKey, object> cqLstner = new MyCq1Listener<TKey, object>();
-        CqQuery<TKey, object>[] vcq = qs.GetCqs<TKey, object>();
-        System.Collections.Generic.List<string> durableCqList = qs.GetAllDurableCqsFromServer();
-        FwkInfo("Durable Cq count is {0} and all cq count is {1}", durableCqList.Count, vcq.Length);
-        //Validate Cq by name
-                 
-        for (int i = 0; i < vcq.Length; i++)
-        {
-          CqQuery<TKey, object> cq = (CqQuery<TKey, object>)vcq.GetValue(i);
-          
-          CqServiceStatistics cqSvcStats = qs.GetCqStatistics();
-          FwkInfo("Number of Cqs created is {0} number of Cqs active is {1} number of Cqs Closed is {2} number of Cqs onClient is {3} number of Cqs stopped is {4} ", cqSvcStats.numCqsCreated(),cqSvcStats.numCqsActive(),cqSvcStats.numCqsClosed(),cqSvcStats.numCqsOnClient(),cqSvcStats.numCqsStopped());
-         
-          CqStatistics cqStats = cq.GetStatistics();
-          CqAttributes<TKey, object> cqAttr = cq.GetCqAttributes();
-          ICqListener<TKey, object>[] vl = cqAttr.getCqListeners();
-          cqLstner = vl[0];
-          MyCq1Listener<TKey, object> myLisner = (MyCq1Listener<TKey, object>)cqLstner;
-          Util.BBSet("CQLISTNERBB", "CQ",myLisner.NumEvents());
-          ResetKey("checkEvents");
-          bool isCheckEvents = GetBoolValue("checkEvents");
-          Util.Log("My count for cq {0} Listener : NumInserts:{1}, NumDestroys:{2}, NumUpdates:{3}, NumEvents:{4}", cq.Name, myLisner.NumInserts(), myLisner.NumDestroys(), myLisner.NumUpdates(), myLisner.NumEvents());
-          if (isCheckEvents)
-          {
-              Int32 createCnt = (Int32)Util.BBGet("OpsBB", "CREATES");
-              Int32 updateCnt = (Int32)Util.BBGet("OpsBB", "UPDATES");
-              Int32 destCnt = (Int32)Util.BBGet("OpsBB", "DESTROYS");
-              Int32 invalCnt = (Int32)Util.BBGet("OpsBB", "INVALIDATES");
-              Int32 totalEvent = createCnt + updateCnt + destCnt + invalCnt;
-
-              ResetKey("invalidate");
-              bool isInvalidate = GetBoolValue("invalidate");
-              ResetKey("stopped");
-              bool isStoped = GetBoolValue("stopped");
-              ResetKey("execute");
-              bool isExecute = GetBoolValue("execute");
-
-              FwkInfo("BB cnt are create = {0} update = {1} destroy = {2} invalidate = {3} TotalEvent = {4} ",createCnt , updateCnt ,destCnt, invalCnt ,totalEvent);
-              if ((!cq.IsStopped()) && isExecute)
-              {
-                  if (isInvalidate)
-                  {
-                      if (myLisner.NumEvents() == totalEvent)
-                          FwkInfo("Events count match ");
-                      else
-                          FwkException(" Total event count incorrect");
-                  }
-                  else
-                  {
-                      if (myLisner.NumInserts() == createCnt && myLisner.NumUpdates() == updateCnt && myLisner.NumDestroys() == destCnt && myLisner.NumEvents() == totalEvent)
-                          FwkInfo("Events count match ");
-                      else
-                          FwkException(" accumulative event count incorrect");
-                  }
-              }
-              else if (isStoped)
-              {
-                  if (cqStats.numEvents() == 0)
-                      FwkInfo("");
-                  else
-                      FwkException("Cq is stopped before entry operation,hence events should not have been received.");
-              }
-
-          }
-          else
-          {
-            //if (myLisner.NumEvents() > 0)
-            {
-              if (myLisner.NumInserts() == cqStats.numInserts() && myLisner.NumUpdates() == cqStats.numUpdates() && myLisner.NumDestroys() == cqStats.numDeletes() && myLisner.NumEvents() == cqStats.numEvents())
-                Util.Log("Accumulative event count is correct");
-              else
-                FwkException("Accumulative event count is incorrect");
-            }
-            //else
-              //FwkException("The listener should have processed some events:");
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("Query.DoVerifyCQListenerInvoked() Caught Exception : {0}", ex);
-      }
-    }
-
-    public void DoValidateEvents()
-    {
-        FwkInfo("validateEvents() called");
-        try
-        {
-          DoVerifyCQListenerInvoked();
-          ResetKey("distinctKeys");
-          ResetKey("NumNewKeys");
-          Int32 numKeys = GetUIntValue("distinctKeys");
-          Int32 numNewKeys = GetUIntValue("NumNewKeys");
-          FwkInfo("NUMKEYS = {0}", numKeys);
-          Int32 clntCnt = GetUIntValue("clientCount");
-          Int32 totalEvents = 0;
-          UInt32 listnEvent = 0;
-          Int32 numDestroyed = (Int32)Util.BBGet("ImageBB", "Last_Destroy") - (Int32)Util.BBGet("ImageBB", "First_Destroy") + 1;
-          Int32 numInvalide = (Int32)Util.BBGet("ImageBB", "Last_Invalidate") - (Int32)Util.BBGet("ImageBB", "First_Invalidate") + 1;
-          Int32 updateCount = (Int32)Util.BBGet("ImageBB", "Last_UpdateExistingKey") - (Int32)Util.BBGet("ImageBB", "First_UpdateExistingKey") + 1;
-          
-            //As CqListener is not invoked when events like "get,localDEstroy and localInvalidate" happen,hence not adding those  events count for correct validation.
-          totalEvents = numNewKeys + numDestroyed +  numInvalide+ updateCount;
-          FwkInfo("TOTALEVENTS = {0}" , totalEvents);
-          listnEvent = (UInt32)Util.BBGet("CQLISTNERBB", "CQ");
-          if (listnEvent == totalEvents)
-          {
-            FwkInfo("ListenerEvents and RegionEvents are equal i.e ListenerEvents = {0} ,RegionEvents = {1}",listnEvent ,totalEvents);
-          }
-          else
-            FwkException("Events mismatch Listner event = {0} and entry event = {1}", listnEvent, totalEvents);
-        }
-        catch (Exception e)
-        { 
-          FwkException("QueryTest::validateEvents() FAILED caught exception  {0}", e.Message);
-        }
-    }
-
-    public void DoVerifyCqDestroyed()
-    {
-      FwkInfo("In QueryTest.DoVerifyCQDestroy()");
-      try
-      {
-        var qs = CheckQueryService();
-        CqQuery<TKey, object>[] vcq = qs.GetCqs<TKey, object>();
-        if (vcq.Length != 0)
-        {
-          FwkException("cqs should have been removed after close");
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("Query.DoVerifyCQDestroy() Caught exception {0}",ex);
-      }
-    }
-
-    public void DoCQState()
-    {
-      FwkInfo("In QueryTest.DoCQState()");
-      string opcode=null;
-      try
-      {
-        opcode = GetStringValue(CqState);
-        var qs = CheckQueryService();
-        CqQuery<TKey, object>[] vcq = qs.GetCqs<TKey, object>();
-        FwkInfo("QueryTest.DoCQState - number of cqs is {0} ", vcq.Length); 
-        for (int i = 0; i < vcq.Length; i++)
-        {
-          CqQuery<TKey, object> cq = (CqQuery<TKey, object>)vcq.GetValue(i);
-          if (opcode == "stopped")
-              cq.Stop();
-          else if (opcode == "closed")
-              cq.Close();
-          else if (opcode == "execute")
-              if (cq.IsStopped())
-              {
-                  cq.Execute();
-              }
-              else
-                  FwkInfo("Cq has not been stopped,it is still running");
-          else
-              FwkException("Invalid operation specified:");
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("Caught unexpected exception during cq {0} operation {1} exiting task ",opcode,ex);
-      }
-    }
-
-    public void DoCQOperation()
-    {
-      FwkInfo("In QueryTest.DoCQOperation()");
-      IRegion<TKey, TVal> region = GetRegion();
-      Int32 secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-      Int32 opsSec = GetUIntValue("opsSecond");
-      opsSec = (opsSec < 1) ? 0 : opsSec;
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-      string opCode = null;
-      Int32 getCQAttributes = 0, getCQName = 0, getQuery = 0, getQueryString = 0, getStatistics = 0, stopCq = 0, closeCq = 0, executeCq = 0, executeCqWithIR = 0;
-      FwkInfo("Operation will work for : {0}" ,secondsToRun);
-      PaceMeter pm = new PaceMeter(opsSec);
-      var qs = CheckQueryService();
-      while (now < end)
-      {
-        try 
-        {
-          opCode=GetStringValue("cqOps");
-          CqQuery<TKey, object>[] vcq = qs.GetCqs<TKey, object>();
-          CqQuery<TKey, object> cqs = (CqQuery<TKey, object>)vcq.GetValue(Util.Rand(vcq.Length));
-          FwkInfo("Performing {0} on cq named {1}",opCode,cqs.Name);
-          if (opCode == null || opCode.Length == 0)
-          {
-            opCode = "no-op";
-          }
-          if(opCode=="getCQAttributes")
-          {
-            cqs.GetCqAttributes();
-            getCQAttributes++;
-          }
-          else if (opCode == "getCQName")
-          {
-            string name = cqs.Name;
-            getCQName++;
-          }
-          else if (opCode == "getQuery")
-          {
-            cqs.GetQuery();
-            getQuery++;
-          }
-          else if (opCode == "getQueryString")
-          {
-            string queryString = cqs.QueryString;
-            getQueryString++;
-          }
-          else if (opCode == "getStatistics")
-          {
-            cqs.GetStatistics();
-            getStatistics++;
-          }
-          else if (opCode == "stopCq")
-          {
-            StopCQ(cqs);
-            stopCq++;
-          }
-          else if (opCode == "closeCQ")
-          {
-            CloseCQ(cqs);
-            closeCq++;
-          }
-          else if (opCode == "executeCQ")
-          {
-            ExecuteCQ(cqs);
-            executeCq++;
-          }
-          else if (opCode == "executeCQWithIR")
-          {
-            ExecuteCQWithIR(cqs);
-            executeCqWithIR++;
-          }
-          else
-          {
-            FwkException("Invalid operation specified {0}", opCode);
-          }
-        }
-        catch(Exception ex)
-        {
-          FwkException("QueryTest.CqOperations() Caught " +
-          "unexpected exception during entry '{0}' operation: {1}.",
-          opCode, ex);
-        }
-        pm.CheckPace();
-        now = DateTime.Now;
-      }
-      Util.Log("cqOperations did {0}getCQAttributes,{1} getCQName,{2}getQuery,{3}getQueryString,{4}getStatistics,{5}stopCQ,{6}closeCQ,{7}executeCQ,{8}executeCQWithIR ", getCQAttributes, getCQName, getQuery, getQueryString, getStatistics, stopCq, closeCq, executeCq, executeCqWithIR);
-    }
-
-    public void StopCQ(CqQuery<TKey, object> cq)
-    {
-      try 
-      {
-        if (cq.IsRunning())
-          cq.Stop();
-        else if (cq.IsStopped())
-        {
-          try
-          {
-            cq.Stop();
-            FwkException("QueryTest.StopCq : should have thrown IllegalStateException. executed stop() successfully on STOPPED CQ");
-          }
-          catch(IllegalStateException)
-          { }
-        }
-        else if (cq.IsClosed())
-        {
-          try
-          {
-            cq.Stop();
-            FwkException("QueryTest::stopCQ : should have thrown CQClosedException. executed stop() successfully on CLOSED CQ");
-          }
-          catch(Exception)
-          {
-            ReRegisterCQ(cq);
-          }
-        }
-      }
-      catch(Exception ex)
-      {
-        FwkException("QueryTest::stopCQ : Caught unexpected exception during cq stop operation :{0}",ex);
-      }
-    }
-
-    public void CloseCQ(CqQuery<TKey, object> cq)
-    {
-      try
-      {
-        if (cq.IsRunning() || cq.IsStopped())
-          cq.Close();
-        if (cq.IsClosed())
-        {
-          try
-          {
-            cq.Close();
-            FwkInfo("Cq {0} is closed ,hence reregistering it before execution");
-            ReRegisterCQ(cq);
-          }
-          catch( CacheClosedException )//should be CqClosedException
-          {
-            FwkException("QueryTest::CloseCQ : Should not have thrown CQClosedException. close() on CLOSED query is not successful");
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTest::closeCQ : Caught unexpected exception during cq close operation: {0}", ex);
-      }
-    }
-
-    public void ExecuteCQ(CqQuery<TKey, object> cq)
-    {
-      try
-      {
-        if (cq.IsStopped())
-          cq.Execute();
-        else if (cq.IsRunning())
-        {
-          try
-          {
-            cq.Execute();
-            FwkException("QueryTest.ExecuteCq : should have thrown IllegalStateException. Execute on RUNNING query is successful");
-          }
-          catch (IllegalStateException)
-          { }
-        }
-        if (cq.IsClosed())
-        {
-          try
-          {
-            cq.Execute();
-            FwkException( "QueryTest::ExecuteCQ : Should have thrown CQClosedException. execute() on CLOSED query is successful");
-          }
-          catch(CacheClosedException) //CqCloseException
-          {
-            FwkInfo("Cq {0} is destroyed ,hence registering it before execution",cq.Name);
-            ReRegisterCQ(cq);
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTest::ExecuteCQ : Caught unexpected exception during cq execute operation:{0} ",ex);
-      }
-    }
-
-    public void ExecuteCQWithIR(CqQuery<TKey, object> cq)
-    {
-      try
-      {
-        if (cq.IsStopped())
-        {
-          ISelectResults<object> results = cq.ExecuteWithInitialResults();
-          FwkInfo("Executed query {0} with initial results",cq.Name);
-        }
-        else if (cq.IsRunning())
-        {
-          try
-          {
-            cq.Execute();
-            FwkException("QueryTest::ExecuteCQWithIR : Should have thrown IllegalStateException. executeWithInitialResults on RUNNING query is successful");
-          }
-          catch (IllegalStateException)
-          {// expected
-          }
-        }
-        if (cq.IsClosed())
-        {
-          try
-          {
-            cq.ExecuteWithInitialResults();
-            FwkException( "QueryTest::ExecuteCQWithIR: Should have thrown CQClosedException. executeWithInitialResults() on CLOSED query is succussful");
-          }
-          catch (CacheClosedException) //CqClosedException
-          {
-            FwkInfo( "CQ:- {0} is closed hence registering it before executeWithInitialResults",cq.Name);
-            ReRegisterCQ(cq);
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTest::executeCQWithIR : Caught unexpected exception during cq executeWithIR operation: {0}",ex);
-      }
-     }
-
-    public void ReRegisterCQ(CqQuery<TKey, object> cq)
-    {
-      try
-      {
-        FwkInfo("re-registering Cq: {0}",cq.Name);
-        string query = cq.QueryString;
-        CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-        ICqListener<TKey, object> cqLstner = new MyCq1Listener<TKey, object>();
-        cqFac.AddCqListener(cqLstner);
-        CqAttributes<TKey, object> cqAttr = cqFac.Create();
-        var qs = CheckQueryService();
-        qs.NewCq(query, cqAttr,false);
-      }
-      catch (Exception ex)
-      {
-        FwkException("Caught unexpected exception during ReRegisterCq() {0}",ex);
-      }
-    }
-
-    public void DoCloseCacheAndReInitialize()
-    {
-      FwkInfo("In QueryTest.DoCloseCacheAndReInitialize()");
-      try
-      {
-        if (m_cache != null)
-        {
-          IRegion<TKey, TVal>[] vregion = CacheHelper<TKey, TVal>.DCache.RootRegions<TKey, TVal>();
-          try
-          {
-            for (Int32 i = 0; i < vregion.Length; i++)
-            {
-              IRegion<TKey, TVal> region = (IRegion<TKey, TVal>)vregion.GetValue(i);
-              region.GetLocalView().DestroyRegion();
-            }
-          }
-          catch (RegionDestroyedException ignore)
-          {
-            string message = ignore.Message;
-            Util.Log(message);
-          }
-          catch (Exception ex)
-          {
-            FwkException("Caught unexpected exception during region local destroy {0}", ex);
-          }
-          bool keepalive = GetBoolValue("keepAlive");
-          bool isDurable = GetBoolValue("isDurable");
-          if (isDurable)
-          {
-            FwkInfo("KeepAlive is {0}", keepalive);
-            m_cache.Close(keepalive);
-          }
-          else
-            m_cache.Close();
-          m_cache = null;
-          FwkInfo("Cache Close");
-        }
-        CacheHelper<TKey, TVal>.Close();
-          DoRestartClientAndRegInt();
-        bool isCq = GetBoolValue("cq");
-        if (isCq)
-          DoRegisterCqForConc();
-      }
-      catch (CacheClosedException ignore)
-      {
-        string message = ignore.Message;
-        Util.Log(message);
-      }
-      catch (Exception ex)
-      {
-        FwkException("Caught unexpected exception during CacheClose {0}",ex);
-      }
-    }
-
-    public void DoRestartClientAndRegInt()
-    {
-      int sleepSec = GetUIntValue("restartTime");
-      if (sleepSec > 0 )
-        Thread.Sleep(sleepSec * 1000);
-      DoCreateUserDefineRegion();
-      string name = GetStringValue("regionName");
-      IRegion<TKey, TVal> region = GetRegion(name);
-      bool isDurable = GetBoolValue("isDurableReg");
-      if (region == null)
-        FwkInfo("DoRestartClientAndRegInt() region is null");
-      else
-        FwkInfo("DoRestartClientAndRegInt()region not null");
-      region.GetSubscriptionService().RegisterAllKeys(isDurable);
-      int waitSec = GetUIntValue("updateReceiveTime");
-      if (waitSec > 0)
-        Thread.Sleep(waitSec * 1000);
-      FwkInfo("DoRestartClientAndRegInt() complete.");
-    }
-
-    public void DoRegisterAllKeys()
-    {
-      FwkInfo("In QueryTest.DoRegisterAllKeys");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        FwkInfo("QueryTest::registerAllKeys region name is {0}",region.Name);
-        bool isDurable = GetBoolValue("isDurableReg");
-        region.GetSubscriptionService().RegisterAllKeys(isDurable);
-        if (isDurable)
-          CacheHelper<TKey, TVal>.DCache.ReadyForEvents();
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTest.DoRegisterAllKeys() caught exception {0}",ex);
-      }
-    }
-
-    public ISelectResults<object> RemoteQuery(QueryService qs, string queryStr)
-    {
-      DateTime startTime;
-      DateTime endTime;
-      TimeSpan elapsedTime;
-      Query<object> qry = qs.NewQuery<object>(queryStr);
-      startTime = DateTime.Now;
-      ISelectResults<object> results = qry.Execute(QueryResponseTimeout);
-      endTime = DateTime.Now;
-      elapsedTime = endTime - startTime;
-      FwkInfo("QueryTest.RemoteQuery: Time Taken to execute" +
-            " the query [{0}]: {1}ms", queryStr, elapsedTime.TotalMilliseconds);
-      return results;
-    }
-
-    public ISelectResults<object> ContinuousQuery(QueryService qs, string queryStr, int cqNum)
-    {
-      DateTime startTime ,endTime;
-      TimeSpan elapsedTime;
-      CqAttributesFactory<TKey, object> cqFac = new CqAttributesFactory<TKey, object>();
-      ICqListener<TKey, object> cqLstner = new MyCq1Listener<TKey, object>();
-      cqFac.AddCqListener(cqLstner);
-      CqAttributes<TKey, object> cqAttr = cqFac.Create();
-      startTime = DateTime.Now;
-      string CqName = String.Format("cq-{0}", cqNum);
-      CqQuery<TKey, object> cq = qs.NewCq(CqName, queryStr, cqAttr, false);
-      ISelectResults<object> results = cq.ExecuteWithInitialResults(QueryResponseTimeout);
-      endTime = DateTime.Now;
-      elapsedTime = endTime - startTime;
-      return results;
-    }
-    
-    public void DoAddRootAndSubRegion()
-    {
-      FwkInfo("In QueryTest.DoAddRootAndSubRegion()");
-      ResetKey("subRegion");
-      bool createSubReg = GetBoolValue("subRegion");
-      try
-      {
-        string isTypeRegistered = GetStringValue("TypeId");
-        if (isTypeRegistered != "registered")
-        {
-          FwkInfo("Getting inside for registeration");
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterType(Position.CreateDeserializable, 7);
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterType(Portfolio.CreateDeserializable, 8);
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterPdxType(Apache.Geode.Client.Tests.PortfolioPdx.CreateDeserializable);
-          CacheHelper<TKey, TVal>.DCache.TypeRegistry.RegisterPdxType(Apache.Geode.Client.Tests.PositionPdx.CreateDeserializable);
-
-        }
-        IRegion<TKey, TVal> parentRegion = null;
-        ResetKey(RegionPaths);
-        string sRegionName;
-        string rootRegionData = GetStringValue("regionSpec");
-        string tagName = GetStringValue("TAG");
-        string endpoints = Util.BBGet(JavaServerBB, EndPointTag + tagName)
-          as string;
-        while ((sRegionName = GetNextRegionName(ref parentRegion)) != null &&
-          sRegionName.Length > 0)
-        {
-          IRegion<TKey, TVal> region;
-          if (parentRegion == null)
-          {
-            region = CreateRootRegion(sRegionName, rootRegionData, endpoints);
-          }
-          else
-          {
-            string fullName = parentRegion.FullPath;
-            Apache.Geode.Client.RegionAttributes<TKey, TVal> regattrs = parentRegion.Attributes;
-            parentRegion.CreateSubRegion(sRegionName, regattrs);
-            Util.BBSet(QueryBB, sRegionName, fullName); parentRegion.SubRegions(false);
-          }
-          if (createSubReg)
-          {
-              CreateSubRegion(sRegionName);
-          }
-      
-        }
-        ResetKey("useTransactions");
-        m_istransaction = GetBoolValue("useTransactions");
-
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTest.DoAddRootAndSubRegion() Caught exception: {0}", ex);
-      }
-      
-    }
-
-    public void CreateSubRegion(string regName) 
-    {
-        IRegion<TKey, TVal> parentRegion = GetRegion();
-        IRegion<TKey, TVal> subRegion;
-        Apache.Geode.Client.RegionAttributes<TKey, TVal> regattrs = parentRegion.Attributes;
-        subRegion = parentRegion.CreateSubRegion(regName,regattrs);
-        ICollection<IRegion<TKey, TVal>> subRegions = parentRegion.SubRegions(true);
-        FwkInfo("subregions are {0}",subRegions.Count);
-    }
-
-    public void DoDestroyUserObject()
-    {
-      FwkInfo("In QueryTests.DoDestroyUserObject()");
-      try
-      {
-        string name = GetStringValue("regionName");
-        IRegion<TKey,TVal> region = GetRegion(name);
-        //string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        ResetKey(DistinctKeys);
-        int numOfKeys = GetUIntValue(DistinctKeys);
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        string objectType = GetStringValue(ObjectType);
-        int setSize = qh.PortfolioSetSize;
-        int destroyKeys = GetUIntValue(DestroyKeys);
-        if (destroyKeys <= 0 && numOfKeys < setSize)
-        {
-          FwkException("QueryTests.DoDestroyUserObject() Number of keys should be multiple of 20");
-        }
-        else
-        {
-          numOfKeys = destroyKeys;
-        }
-
-        int numSet = numOfKeys / setSize;
-
-        FwkInfo("QueryTests.DoDestroyUserObject() Destroying " + numOfKeys + " keys, destroyKeys=" + destroyKeys +
-          ", setSize=" + setSize + ", numSet=" + numSet);
-        if (m_istransaction)
-        {
-          txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-          txManager.Begin();
-        }
-        qh.DestroyPortfolioOrPositionData(region, setSize, numSet, objectType);
-        if (m_istransaction)
-          txManager.Commit();
-        FwkInfo("QueryTests.DoDestroyUserObject() Destroyed user objects.");
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTests.DoDestroyUserObject() Caught Exception: {0}", ex);
-      }
-    }
-
-    public void DoInvalidateUserObject()
-    {
-      FwkInfo("In QueryTests.DoInvalidateUserObject().");
-      try
-      {
-        string name = GetStringValue("regionName");
-        IRegion<TKey, TVal> region = GetRegion(name);
-        //string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        ResetKey(DistinctKeys);
-        int numOfKeys = GetUIntValue(DistinctKeys);
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        string objectType = GetStringValue(ObjectType);
-        int setSize = qh.PortfolioSetSize;
-        int invalidateKeys = GetUIntValue(InvalidateKeys);
-        if (invalidateKeys <= 0 && numOfKeys < setSize)
-        {
-          FwkException("QueryTests.DoInvalidateUserObject() Number of keys should be multiple of 20");
-        }
-        else
-        {
-          numOfKeys = invalidateKeys;
-        }
-
-        int numSet = numOfKeys / setSize;
-
-        FwkInfo("QueryTests.DoInvalidateUserObject() Invalidating " + numOfKeys +
-          " keys, invalidateKeys=" + invalidateKeys + ", setSize=" + setSize + ", numSet=" + numSet);
-        if (m_istransaction)
-        {
-          txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-          txManager.Begin();
-        }
-        qh.InvalidatePortfolioOrPositionData(region, setSize, numSet, objectType);
-        if (m_istransaction)
-           txManager.Commit();
-        
-        FwkInfo("QueryTests.DoInvalidateUserObject() Destroyed user objects.");
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTests.DoInvalidateUserObject() caught Exception: {0}", ex);
-      }
-    }
-
-    public void DoPopulateUserObject()
-    {
-      FwkInfo("In QueryTest.PopulateUserObject().");
-      try
-      {
-        string name = GetStringValue("regionName");
-        IRegion<TKey, TVal> region = GetRegion(name);
-        //string label = CacheHelper<TKey, TVal>.RegionTag(region.Attributes);
-        ResetKey(DistinctKeys);
-        int numOfKeys = GetUIntValue(DistinctKeys); // number of keys should be multiple of 20
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        int numSet = 0;
-        int setSize = 0;
-        // Loop over value sizes
-        ResetKey(ValueSizes);
-        int objSize;
-        string objectType = GetStringValue(ObjectType);
-        
-        while ((objSize = GetUIntValue(ValueSizes)) > 0)
-        { // value sizes loop
-          if (m_istransaction)
-          {
-            txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-            txManager.Begin();
-          }
-          if (objectType == "Portfolio")
-          {
-            setSize = qh.PortfolioSetSize;
-            if (numOfKeys < setSize)
-            {
-              FwkException("QueryTests.PopulateUserObject: Number of keys" +
-                " should be multiple of 20");
-            }
-            numSet = numOfKeys / setSize;
-            qh.PopulatePortfolioData(region, setSize, numSet, objSize);
-          }
-          else if (objectType == "Position")
-          {
-            setSize = qh.PositionSetSize;
-            if (numOfKeys < setSize)
-            {
-              FwkException("QueryTests.PopulateUserObject: Number of keys" +
-                " should be multiple of 20");
-            }
-            numSet = numOfKeys / setSize;
-            qh.PopulatePositionData(region, setSize, numSet);
-          }
-          if (objectType == "PortfolioPdx")
-          {
-            setSize = qh.PortfolioSetSize;
-            if (numOfKeys < setSize)
-            {
-              FwkException("QueryTests.PopulateUserObject: Number of keys" +
-                " should be multiple of 20");
-            }
-            numSet = numOfKeys / setSize;
-            qh.PopulatePortfolioPdxData(region, setSize, numSet, objSize);
-          }
-          else if (objectType == "PositionPdx")
-          {
-            setSize = qh.PositionSetSize;
-            if (numOfKeys < setSize)
-            {
-              FwkException("QueryTests.PopulateUserObject: Number of keys" +
-                " should be multiple of 20");
-            }
-            numSet = numOfKeys / setSize;
-            qh.PopulatePositionPdxData(region, setSize, numSet);
-          }
-          if(m_istransaction)
-            txManager.Commit();
-          FwkInfo("QueryTests.PopulateUserObject: Done populating {0} objects",
-            objectType);
-
-          Thread.Sleep(1000); // Put a marker of inactivity in the stats
-        } // valueSizes loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTests.PopulateUserObject: Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(3000); // Put a marker of inactivity in the stats
-      FwkInfo("QueryTests.PopulateUserObject complete.");
-    }
-
-    public void DoGetObject()
-    {
-      FwkInfo("In QueryTests.GetObject.");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        ResetKey(DistinctKeys);
-        int numOfKeys = GetUIntValue(DistinctKeys);
-
-        string objectType = GetStringValue(ObjectType);
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        int setSize = qh.PortfolioSetSize;
-        if (numOfKeys < setSize)
-        {
-          setSize = numOfKeys;
-        }
-        int numSets = numOfKeys / setSize;
-
-        TVal valuepos;
-        TKey keypos;
-        for (int set = 1; set <= numSets; set++)
-        {
-          for (int current = 1; current <= setSize; current++)
-          {
-            string posname = null;
-            if (objectType == "Portfolio" || (objectType == "PortfolioPdx"))
-            {
-              posname = string.Format("port{0}-{1}", set, current);
-            }
-            else if (objectType == "Position" || (objectType == "PositionPdx"))
-            {
-              posname = string.Format("pos{0}-{1}", set, current);
-            }
-            
-            keypos = (TKey)(object)posname;
-            if (m_istransaction)
-            {
-              txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-              txManager.Begin();
-            }
-            valuepos = region[keypos];
-            if (m_istransaction)
-              txManager.Commit();
-            if (valuepos == null)
-            {
-              FwkException("QueryTests.GetObject: Could not find key [{0}]" +
-                " in region.", keypos);
-            }
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTests.GetObject: Caught Exception: {0}", ex);
-      }
-      FwkInfo("QueryTests.GetObject complete.");
-    }
-
-    public void DoRunQuery()
-    {
-      FwkInfo("In QueryTests.RunQuery");
-      try
-      {
-        string queryType = GetStringValue(QueryResultType);
-        string query = GetStringValue(QueryString); // set the query string in xml
-        if (queryType == "resultSet")
-        {
-          FwkInfo("QueryTests.RunQuery: Calling VerifyResultSet");
-          if (!VerifyResultSet())
-          {
-            FwkException("QueryTests.RunQuery: failed in VerifyResultSet");
-          }
-        }
-        else if (queryType == "structSet")
-        {
-          FwkInfo("QueryTests.RunQuery: Calling VerifyStructSet");
-          if (!VerifyStructSet())
-          {
-            FwkException("QueryTests.RunQuery: failed in VerifyStructSet");
-          }
-        }
-        else if (query != null && query.Length > 0)
-        {
-          FwkInfo("QueryTests.RunQuery: Reading query from xml: {0}",
-            query);
-          if (!ReadQueryString(ref query))
-          {
-            FwkException("QueryTests.RunQuery: Failed in ReadQueryString");
-          }
-        }
-        else
-        {
-          FwkException("QueryTests.RunQuery: Query type: {0} is not supported",
-            queryType);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("QueryTests.RunQuery: Caught Exception: {0}", ex);
-      }
-      FwkInfo("QueryTests.RunQuery complete.");
-    }
-
-    public void DoRunQueryWithPayloadAndEntries()
-    {
-      try
-      {
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        int numSet = 0;
-        int setSize = 0;
-        //populating data
-        ResetKey(DistinctKeys);
-        int numOfKeys; // number of key should be multiple of 20
-        while ((numOfKeys = GetUIntValue(DistinctKeys)) > 0)
-        { // distinctKeys loop
-          ResetKey(ValueSizes);
-          int objSize;
-          while ((objSize = GetUIntValue(ValueSizes)) > 0)
-          { // valueSizes loop
-            FwkInfo("DoRunQueryWithPayloadAndEntries() Populating {0} " +
-              "entries with {1} payload size", numOfKeys, objSize);
-            ResetKey(RegionName);
-            IRegion<TKey, TVal> region;
-            while ((region = GetRegion()) != null)
-            {
-              string regionName = region.Name;
-              if ((regionName == "Portfolios") ||
-                (regionName == "Portfolios2") ||
-                (regionName == "Portfolios3"))
-              {
-                FwkInfo("DoRunQueryWithPayloadAndEntries() " +
-                  "Populating Portfolio object to region " + region.FullPath);
-                setSize = qh.PortfolioSetSize;
-                if (numOfKeys < setSize)
-                {
-                  FwkException("doRunQueryWithPayloadAndEntries : " +
-                    "Number of keys should be multiple of 20");
-                }
-                numSet = numOfKeys / setSize;
-                qh.PopulatePortfolioData(region, setSize, numSet, objSize);
-              }
-              else if ((regionName == "Positions") ||
-                (regionName == "/Portfolios/Positions"))
-              {
-                FwkInfo("DoRunQueryWithPayloadAndEntries() " +
-                  "Populating Position object to region " + region.FullPath);
-                setSize = qh.PositionSetSize;
-                if (numOfKeys < setSize)
-                {
-                  FwkException("DoRunQueryWithPayloadAndEntries : " +
-                    "Number of keys should be multiple of 20");
-                }
-                numSet = numOfKeys / setSize;
-                qh.PopulatePositionData(region, setSize, numSet);
-              }
-            }
-            FwkInfo("Populated User objects");
-            Thread.Sleep(10000);
-            // running queries
-            FwkInfo("DoRunQueryWithPayloadAndEntries: " +
-              "Calling VerifyResultSet ");
-            if (!VerifyResultSet(numOfKeys))
-            {
-              FwkException("DoRunQueryWithPayloadAndEntries: " +
-                "Failed in VerifyResultSet");
-            }
-            FwkInfo("DoRunQueryWithPayloadAndEntries: " +
-              "Calling VerifyStructSet");
-            if (!VerifyStructSet(numOfKeys))
-            {
-              FwkException("DoRunQueryWithPayloadAndEntries: " +
-                "Failed in VerifyStructSet");
-            }
-            Thread.Sleep(3000); // Put a marker of inactivity in the stats
-          } // valueSizes loop
-          Thread.Sleep(2000);
-        }// distinctKeys loop
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRunQueryWithPayloadAndEntries() Caught Exception: {0}", ex);
-      }
-      Thread.Sleep(4000); // Put a marker of inactivity in the stats
-      FwkInfo("DoRunQueryWithPayloadAndEntries() complete.");
-    }
-
-    public void DoCloseCache()
-    {
-      FwkInfo("In QueryTests.CloseCache");
-
-      CacheHelper<TKey, TVal>.Close();
-
-      FwkInfo("QueryTests.CloseCache complete.");
-    }
-
-    public void DoPopulateRangePositions()
-    {
-      FwkInfo("In QueryTests.DoPopulateRangePositions");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-
-        int rangeStart = GetUIntValue("range-start");
-        int rangeEnd = GetUIntValue("range-end");
-
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-        if (m_istransaction)
-        {
-          txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-          txManager.Begin();
-        }
-        qh.PopulateRangePositionData(region, rangeStart, rangeEnd);
-        if(m_istransaction)
-          txManager.Commit();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoPopulateRangePositions() Caught Exception: {0}", ex);
-      }
-
-      FwkInfo("DoPopulateRangePositions() complete.");
-    }
-
-    public void DoGetAndComparePositionObjects()
-    {
-      FwkInfo("In QueryTests.DoGetAndComparePositionObjects");
-
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-
-        int rangeStart = GetUIntValue("range-start");
-        int rangeEnd = GetUIntValue("range-end");
-
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-
-        for (int i = rangeStart; i <= rangeEnd; i++)
-        {
-          TVal cachedPos = qh.GetCachedPositionObject(region, i);
-          TVal generatedPos = qh.GetExactPositionObject(i);
-
-          if (!qh.CompareTwoPositionObjects(cachedPos, generatedPos))
-          {
-            FwkSevere("QueryTest:DoGetAndComparePositionObjects: objects not same for index " + i);
-          }
-        }
-
-        qh.PopulateRangePositionData(region, rangeStart, rangeEnd);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoGetAndComparePositionObjects() Caught Exception: {0}", ex);
-      }
-
-      FwkInfo("DoGetAndComparePositionObjects() complete.");
-    }
-
-    public void DoUpdateRangePositions()
-    {
-      FwkInfo("In QueryTests.DoUpdateRangePositions");
-
-      try
-      {
-        int maxRange = GetUIntValue("range-max");
-        int secondsToRun = GetTimeValue("workTime");
-
-        DateTime nowTime = DateTime.Now;
-        DateTime endTime = DateTime.Now;
-        endTime = endTime.AddSeconds(secondsToRun);
-
-        IRegion<TKey, TVal> region = GetRegion();
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-
-        while (nowTime < endTime)
-        {
-          qh.PutExactPositionObject(region, Util.Rand(maxRange));
-          nowTime = DateTime.Now;
-        }        
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoUpdateRangePositions() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoUpdateRangePositions() complete.");
-    }
-
-    public void DoVerifyAllPositionObjects()
-    {
-      FwkInfo("In QueryTests.DoVerifyAllPositionObjects");
-
-      try
-      {
-        int maxRange = GetUIntValue("range-max");
-        IRegion<TKey, TVal> region = GetRegion();
-        QueryHelper<TKey, TVal> qh = QueryHelper<TKey, TVal>.GetHelper(CacheHelper<TKey, TVal>.DCache);
-
-        for (int i = 1; i <= maxRange; i++)
-        {
-          TVal pos1 = qh.GetCachedPositionObject(region, i);
-          TVal pos2 = qh.GetExactPositionObject(i);
-          if (!qh.CompareTwoPositionObjects(pos1, pos2))
-          {
-            FwkSevere("QueryTests.VerifyAllPositionObjects: objects not same for index " + i);
-          }
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoVerifyAllPositionObjects() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoVerifyAllPositionObjects() complete.");
-    }
-
-    #endregion
-
-  }
-}
diff --git a/tests/cli/NewFwkLib/ResumableTx/ResumableTx.cs b/tests/cli/NewFwkLib/ResumableTx/ResumableTx.cs
deleted file mode 100644
index 8ac30ca..0000000
--- a/tests/cli/NewFwkLib/ResumableTx/ResumableTx.cs
+++ /dev/null
@@ -1,1241 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-
-  public class EntryTxTask<TKey, TVal> : ClientTask
-  {
-    #region Private members
-
-    static protected int BEGIN_TX = 1001;
-    static protected int EXECUTE_TX_OPS = 1002;
-    static protected int EXECUTE_NONTX_OPS = 1003;
-    static protected int COMMIT_TX = 1004;
-    static protected int ROLLBACK_TX = 1005;
-
-
-    private IRegion<TKey, TVal> m_region;
-    private static int keyCount = 0;
-    private static int kCount = 0;
-    private int m_MaxKeys;
-    private static Dictionary<TransactionId, object> activeTxns;
-    private static Dictionary<IRegion<TKey, TVal>, Dictionary<TKey, TVal>> OpMap;
-    private object txlock = new object();
-    private List<TransactionId> keyList ;
-    private Int32 m_create;
-    private Int32 m_update;
-    private Int32 m_destroy;
-    //private Int32 m_invalidate;
-    private Int32 m_cnt;
-    //bool m_isDestroy;
-    bool m_finish;
-    bool m_beginTx;
-    bool m_commitTx;
-    private object CLASS_LOCK = new object();
-    private const string SerialExc = "isSerialExecution";
-    private const string ConcurrentExc = "isConcurrentExecution";
-    private const string WorkTime = "workTime";
-   
-    #endregion
-
-    private static String getClientIdString()
-    {
-      return "Cl_Id" + Util.ClientId + "_thr_" + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString();
-    }
-
-   public TxInfo begin(IRegion<TKey,TVal> region)
-    {
-      CacheTransactionManager txManager = null;
-      IRegion<TKey, TVal> reg = region;
-      TransactionId id = null;
-      TxInfo txInfo = new TxInfo();
-      txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-      try
-      {
-        txManager.Begin();
-        try
-        {
-          kCount++;
-          TKey key = (TKey)(object)(kCount);
-          TVal value = GetValue();
-          reg[key] = value;
-          Util.Log("The Key is={0} and value={1}", key.ToString(),value.ToString());
-        }
-        catch (Exception e)
-        {
-          FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught {0}", e);
-        }
-      }
-      catch (IllegalStateException e)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught {0}", e);
-      }
-      try
-      {
-        id = txManager.Suspend();
-        Util.Log("Suspend() complete ");
-      }
-      catch (IllegalStateException e)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException("Got {0}", e);
-      }
-      Util.Log("BEGIN_TX returning txId = {0}",id);
-      try
-      {
-       txInfo.setTxId(id);
-      }
-      catch (Exception e) 
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkException("Got this {0}", e);
-      }
-     
-      return txInfo;
-    }
-
-    public bool commit(TxInfo txInfo)
-    {
-      TransactionId id = (TransactionId)(object)txInfo.getTxId();
-      bool commited = false;
-      CacheTransactionManager txManager = null;
-      txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-      if (txManager.TryResume(id, TimeSpan.FromMilliseconds(30000)))
-      {
-        try
-        {
-          txManager.Commit();
-          commited = true;
-        }
-        catch (CommitConflictException ex)
-        {
-          //Expected exception with concurrent transactions.
-          Util.Log("Got expected exception {0}", ex);
-        }
-        catch (TransactionDataRebalancedException ex)
-        {
-          FwkTest<TKey, TVal>.CurrentTest.FwkException("Got {0}", ex);
-        }
-        catch (TransactionDataNodeHasDepartedException ex)
-        {
-          FwkTest<TKey, TVal>.CurrentTest.FwkException("Got {0}", ex);
-        }
-      }
-      else
-        Util.Log("TxId {0} is not suspended in this member with tryResume time limit, cannot commit.  Expected, continuing test.");
-      Util.Log("Commited returning {0}",commited);
-      return commited;
-     
-    }
-
-    public void rollback(TxInfo txInfo)
-    {
-      TransactionId id = (TransactionId)(object)txInfo.getTxId();
-      CacheTransactionManager txManager = null;
-      bool isRollBack = false;
-      txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-      if (txManager.TryResume(id, TimeSpan.FromMilliseconds(30000)))
-      {
-         txManager.Rollback();
-         isRollBack = true;
-      }
-      else
-        Util.Log("TxId {0} is not suspended in this member with tryResume time limit, cannot rollback.  Expected with concurrent execution, continuing test.");
-      Util.Log("RollbackTx returning {0}",isRollBack);
-   
-    }
-
-    public void executeTxOps(TxInfo txInfo)
-    {
-      //This will do a resume+doOps+suspend
-      TransactionId id = (TransactionId)(object)txInfo.getTxId();
-      CacheTransactionManager txManager = null;
-      txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-      bool executedOps = false;
-      int numOfOpsToDo = 5;
-      if (txManager.TryResume(id, TimeSpan.FromMilliseconds(30000)))
-      {
-        try
-        {
-          doEntryOps(numOfOpsToDo);
-          executedOps = true;
-        }
-        catch (TransactionDataNodeHasDepartedException ex)
-        {
-          FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught {0}", ex);
-        }
-        catch (TransactionDataRebalancedException ex)
-        {
-          FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught {0}", ex);
-        }
-        catch (Exception ex)
-        {
-          FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught unexpected exception during doEntryOps task {0}", ex.Message);
-        }
-        finally
-        {
-          id = txManager.Suspend();
-          Util.Log("Suspend() complete txId is {0}", id);
-        }
-      }
-      Util.Log("EXECUTE_TX returned  {0}", executedOps);
-    }
-
-    public void doEntryOps(int numOfOpsToDo)
-    {
-      int numOpsCompleted = 0;
-      string opcode = null;
-      List<string> opList = new List<string>();
-      IRegion<TKey, TVal> region = m_region;
-      int size = 0;
-      int create = 0, update = 0, destroy = 0, invalidate = 0, localdestroy = 0, /*localinvalidate = 0,*/
-        get = 0/*, putall = 0*/;
-      try
-        {
-          size = region.Count;
-          opcode = FwkTest<TKey, TVal>.CurrentTest.GetStringValue("entryOps");
-          Util.Log("Op code is {0} and numOf opsCompleted is {1} and Regionsize is {2}", opcode, numOpsCompleted, size);
-          if (opcode == null) opcode = "no-opcode";
-          if (((size < 1) && (opcode != "create")) || (opcode == "create"))
-          {
-            opcode = "create";
-            addEntry(region);
-            Interlocked.Increment(ref m_create);
-            create++;
-          }
-          else if (opcode == "update")
-          {
-            updateEntry(region);
-            Interlocked.Increment(ref m_update);
-            update++;
-          }
-          else if (opcode == "destroy")
-          {
-            destroyEntry(region, false);
-            Interlocked.Increment(ref m_destroy);
-            destroy++;
-          }
-          else if (opcode == "localDestroy")
-          {
-            destroyEntry(region, true);
-            //Interlocked.Increment();
-            localdestroy++;
-          }
-          else if (opcode == "get")
-          {
-            getKey(region);
-            get++;
-          }
-          else if (opcode == "invalidate")
-          {
-            invalidateEntry(region,false);
-            invalidate++;
-          }
-          else
-          {
-            FwkTest<TKey, TVal>.CurrentTest.FwkException("CacheServer.doEntryOps() Invalid operation " +
-             "specified: {0}", opcode);
-          }
-          numOpsCompleted++;
-          opList.Add(opcode);
-          
-        }
-        catch (Exception ex)
-        {
-          FwkTest<TKey, TVal>.CurrentTest.FwkException("CacheServer.doEntryOps() Caught unexpected " +
-            "exception during entry '{0}' operation: {1}.", opcode, ex);
-        }
-        Util.Log("DoEntryOP: create = {0}, update = {1}, destroy = {2},get = {3} invalidate={4}, num of Ops ={5}",
-        m_create, m_update, m_destroy, get, invalidate, numOpsCompleted);
-    }
-    
-    protected TKey addEntry(IRegion<TKey, TVal> m_region)
-    {
-      TKey key = GetNewKey();
-      TVal value = GetValue();
-      //int beforeSize = 0;
-      bool isSerialExecution = false;
-      Dictionary<TKey, TVal> addMap = new Dictionary<TKey, TVal>();
-      try
-      {
-        m_region.Add(key, value);
-        addMap[key] = value;
-        OpMap[m_region] = addMap;
-        doEdgeClientValidation();
-      }
-      catch (EntryExistsException ex)
-      {
-        if (isSerialExecution)
-        {
-          // cannot get this exception; nobody else can have this key
-          throw new Exception(ex.StackTrace);
-        }
-        else
-        {
-          Util.Log("Caught {0} (expected with concurrent execution); continuing with test", ex);
-        }
-      }
-      return key;
-    }
-
-    protected void updateEntry(IRegion<TKey, TVal> r)
-    {
-      TKey key = GetExistingKey(true,r);
-      TVal value = GetValue();
-      Dictionary<TKey, TVal> updateMap = new Dictionary<TKey, TVal>();
-      r[key] = value;
-      updateMap[key] = value;
-      OpMap[m_region] = updateMap;
-      doEdgeClientValidation();
-    }
-
-    protected void invalidateEntry(IRegion<TKey, TVal> r, bool isLocalInvalidate)
-    {
-      TKey key = GetExistingKey(true,r);
-      bool containsKey = m_region.GetLocalView().ContainsKey(key);
-      bool containsValueForKey = m_region.GetLocalView().ContainsValueForKey(key);
-      Util.Log("containsKey for " + key + ": " + containsKey);
-      Util.Log("containsValueForKey for " + key + ": " + containsValueForKey);
-      try
-      {
-        if (isLocalInvalidate)
-        { // do a local invalidate
-          m_region.GetLocalView().Invalidate(key);
-        }
-        else
-        { // do a distributed invalidate
-          m_region.Invalidate(key);
-        }
-      }
-      catch (EntryNotFoundException e)
-      {
-         Util.Log("Caught {0} (expected); continuing with test", e);
-          return;
-        
-      }
-    }
-
-    protected void destroyEntry(IRegion<TKey, TVal> m_region, bool isLocalDestroy)
-    {
-      TKey key = GetExistingKey(true, m_region);
-      bool isSerialExecution = false;
-      try
-      {
-        if (isLocalDestroy)
-        { // do a local invalidate
-          m_region.GetLocalView().Remove(key);
-        }
-        else
-        { // do a distributed invalidate
-          m_region.Remove(key);
-        }
-      }
-      catch (EntryNotFoundException e)
-      {
-        if (isSerialExecution)
-          throw new Exception(e.StackTrace);
-        else
-        {
-          Util.Log("Caught {0} (expected with concurrent execution); continuing with test", e);
-          return;
-        }
-      }
-    }
-
-    protected void getKey(IRegion<TKey, TVal> aRegion)
-    {
-      TKey key = GetExistingKey(true,aRegion);
-      TVal anObj = default(TVal);
-      try
-      {
-        anObj = aRegion[key];
-      }
-      catch (Apache.Geode.Client.KeyNotFoundException)
-      {
-        if (!EqualityComparer<TVal>.Default.Equals(anObj, default(TVal)))
-        {
-          throw new Apache.Geode.Client.KeyNotFoundException();
-        }
-
-      }
-    }
-
-    protected TKey GetExistingKey(bool useServerKeys,IRegion<TKey,TVal> region)
-    {
-      TKey key = default(TKey);
-        if (useServerKeys)
-        {
-          int size = region.Count;
-          TKey[] keys = (TKey[])region.Keys;
-          key = keys[Util.Rand(0, size)];
-        }
-        else
-        {
-          int size = region.GetLocalView().Count;
-          TKey[] keys = (TKey[])region.GetLocalView().Keys;
-          key = keys[Util.Rand(0, size)];
-        }
-        return key;
-    }
-
-    protected TKey GetNewKey()
-    {
-      keyCount++;
-      FwkTest<TKey, TVal>.CurrentTest.ResetKey("distinctKeys");
-      int numKeys = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("distinctKeys");
-     // String keybuf = String.Format("Key-{0}-{1}-{2}", Util.PID, Util.ThreadID, keyCount);
-      TKey key = (TKey)(object)(keyCount);
-    //  keyCount++;
-      return key;
-    }
-
-    protected TVal GetValue()
-    {
-      TVal tmpValue = default(TVal);
-      FwkTest<TKey,TVal>.CurrentTest.ResetKey("valueSizes");
-      int size = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("valueSizes");
-      StringBuilder builder = new StringBuilder();
-      Random random = new Random();
-      char ch;
-      for (int j = 0; j < size; j++)
-      {
-        ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
-        builder.Append(ch);
-      }
-      if (typeof(TVal) == typeof(string))
-      {
-        tmpValue = (TVal)(object)builder.ToString();
-      }
-      else if (typeof(TVal) == typeof(byte[]))
-      {
-        tmpValue = (TVal)(object)(Encoding.ASCII.GetBytes(builder.ToString()));
-      }
-      return tmpValue;
-    }
-
-    public void doTransactions(IRegion<TKey,TVal> region)//,Dictionary<TransactionId, object> m_maps)
-    {
-      Util.Log("Inside ResumableTx:doTransactions()");
-      TransactionId txId = null;
-      //String txIdStr = "";
-      TxInfo txInfo = null;
-      IRegion<TKey, TVal> reg = region;
-      int action = 0;
-      FwkTest<TKey, TVal>.CurrentTest.ResetKey("minExecutions");
-      int minExecutions = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("minExecutions");
-      int numExecutions = 0;
-      Util.Log("activeTx map count is {0}",activeTxns.Count);
-      if (activeTxns.Count > 0)
-      {
-        try
-        {
-          keyList = new List<TransactionId>(activeTxns.Keys);
-        }
-        catch (Exception e) { FwkTest<TKey, TVal>.CurrentTest.FwkException("Inside keylist exception  {0}", e); }
-      }
-      FwkTest<TKey, TVal>.CurrentTest.ResetKey("numThreads");
-      string NUMTHREADS = "numThreads";
-      FwkTest<TKey, TVal>.CurrentTest.ResetKey(NUMTHREADS);
-      int numActiveThd = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue(NUMTHREADS);
-      int numActiveTx = activeTxns.Count;
-      try
-      {
-        Util.Log("numAvtiveTx is {0} and no of AvtiveThread = {1} and activemap count= {2}", numActiveTx, numActiveThd,activeTxns.Count);
-      }
-      catch (Exception e) { FwkTest<TKey, TVal>.CurrentTest.FwkException("Caught exception {0}",e); }
-      lock (CLASS_LOCK)
-      {
-      if (numActiveTx < numActiveThd)
-        {
-          action = BEGIN_TX;
-        }
-        else
-        {
-          for (int i = 0; i < keyList.Count; i++)
-          {
-            txId = (TransactionId)(object)keyList[i];
-            txInfo = (TxInfo)(object)activeTxns[txId];
-           
-            numExecutions = txInfo.getNumExecutions();
-            if (numExecutions > minExecutions)
-            {
-              bool isCommit = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue("TxBool");
-              if (isCommit)
-              {
-                action = COMMIT_TX;
-              }
-              else
-              {
-                action = ROLLBACK_TX;
-              }
-              break;
-            }
-          }
-          if (action == 0)
-          {
-            action = EXECUTE_TX_OPS;
-            Random random = new Random();
-            int rant = random.Next(0, keyList.Count - 1);
-            txId = (TransactionId)(object)keyList[rant];
-            txInfo = (TxInfo)(object)activeTxns[txId];
-          }
-        }
-      }
-       Boolean success = false;
-       try
-       {
-         lock (txlock)
-         {
-           switch (action)
-           {
-             case (1001):
-               txInfo = begin(reg);
-               txId = txInfo.getTxId();
-               activeTxns[txId] = (Object)txInfo;
-               break;
-             case (1002):
-               executeTxOps(txInfo);
-               txId = txInfo.getTxId();
-               txInfo = (TxInfo)(object)activeTxns[txId];
-               if(txInfo != null)
-               {  // could happen if tx committed, entry removed
-                 txInfo.incrementNumExecutions();
-                 activeTxns[txId] = (Object)txInfo;
-               }
-               break;
-             case (1004):
-               success = commit(txInfo);
-               break;
-             case (1005):
-               rollback(txInfo);
-               txId = txInfo.getTxId();
-               activeTxns.Remove(txId);
-               break;
-           }
-         }
-       }
-       catch (Exception e)
-       {
-         FwkTest<TKey, TVal>.CurrentTest.FwkException("The Test Threw this exception {0}", e);
-       }
-    }
-
-    public void doSerialExecution(IRegion<TKey, TVal> region)
-    {
-       Util.Log("Inside ResumableTX doSerialExecution()");
-       keyList = new List<TransactionId>(activeTxns.Keys);
-       TxInfo txInfo;
-       TransactionId txId = null;
-       for (int i = 0; i < keyList.Count; i++)
-       {
-         txInfo = (TxInfo)activeTxns[keyList[i]];
-         txId = (TransactionId)(object)txInfo.getTxId();
-         //bool executedOps;
-         try
-         {
-           executeTxOps(txInfo);
-         }
-         catch (Exception ex)
-         {
-           Util.Log("Caught {0} while executing tx ops", ex);
-           //executedOps = false;
-         }
-         txInfo.incrementNumExecutions();
-         activeTxns[txId] = (Object)txInfo;
-       }
-     }
-
-    public void doEdgeClientValidation()
-    {
-      //Validate the number of expected key/values and no. of destroyed entries.
-      Util.Log("Verifying expected keys/values");
-      Util.Log("Region count is {0} and local region count is {1}",m_region.Count,m_region.GetLocalView().Count);
-      TKey key;
-      TVal val;
-      bool success = true;
-      lock (OpMap)
-      {
-        foreach (KeyValuePair<IRegion<TKey, TVal>, Dictionary<TKey, TVal>> kvp in OpMap)
-        {
-          IRegion<TKey, TVal> myregion = (IRegion<TKey, TVal>)kvp.Key;
-          Dictionary<TKey, TVal> mapp = (Dictionary<TKey, TVal>)kvp.Value;
-          foreach (KeyValuePair<TKey, TVal> sp in mapp)
-          {
-            key = sp.Key;
-            val = sp.Value;
-            if (!m_region.ContainsKey(key))
-            {
-              FwkTest<TKey, TVal>.CurrentTest.FwkException("Expected containsKey() to be true for key {0} ,but it was false", key);
-              success = false;
-            }
-            if (val != null && !m_region.ContainsValueForKey(key))
-            {
-              FwkTest<TKey, TVal>.CurrentTest.FwkException("Expected containsValueForKey() to be true for key {0} ,but it was false", key);
-              success = false;
-            }
-          }
-        }
-      }
-      if (!success)
-        FwkTest<TKey, TVal>.CurrentTest.FwkException("edge client validation failed");
-      else
-        Util.Log("Done executing doEdgeClientValidation - validation successful");
-        
-    }
-
-    public void finishAllActiveTx(Dictionary<TransactionId,object> activeTX,Boolean isCommit)
-    {
-      lock (CLASS_LOCK)
-      {
-        Util.Log("In Finish active map count is {0}",activeTX.Count);
-        keyList = new List<TransactionId>(activeTX.Keys);
-        bool txCompleted = false;
-        for (int i = 0; i < keyList.Count; i++)
-        {
-          TransactionId txId = (TransactionId)(object)keyList[i];
-          TxInfo txInfo = (TxInfo)(object)activeTX[txId];
-          try
-          {
-            txCompleted = commit(txInfo);
-            Util.Log("Commit got {0}",txCompleted);
-          }
-          catch (Exception e)
-          {
-            FwkTest<TKey, TVal>.CurrentTest.FwkException("Got this exception {0}", e);
-          }
-          finally 
-          { 
-            activeTX.Remove(txId);
-          }
-          Util.Log("After commit/update the Active Map is {0}", activeTX.Count);
-        }
-      }
-      
-    }
-
-    public EntryTxTask(IRegion<TKey, TVal> region, int keyCnt, Dictionary<TransactionId, object> maps,Dictionary<IRegion<TKey,TVal>,Dictionary<TKey,TVal>>omaps, Boolean finish,Boolean isBeginTx,Boolean isCommitTx)
-      : base()
-    {
-      m_region = region;
-      m_MaxKeys = keyCnt;
-      activeTxns = maps;
-      OpMap = omaps;
-      m_create = 0;
-      m_update = 0;
-      m_destroy = 0;
-      //m_invalidate = 0;
-      m_cnt = 0;
-      //m_isDestroy = true;
-      m_finish = finish;
-      m_beginTx = isBeginTx;
-      m_commitTx = isCommitTx;
-    }
-    public override void DoTask(int iters, object data)
-    {
-      Int32 localcnt = m_cnt;
-      Interlocked.Increment(ref m_cnt);
-      int offset = Util.Rand(m_MaxKeys);
-      int count = offset;
-      //TKey key = default(TKey);
-      //TVal value = default(TVal);
-      FwkTest<TKey, TVal>.CurrentTest.ResetKey(SerialExc);
-      bool isSerialExecution = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue(SerialExc);
-   
-      FwkTest<TKey, TVal>.CurrentTest.ResetKey(ConcurrentExc);
-      bool isConcExecution = FwkTest<TKey, TVal>.CurrentTest.GetBoolValue(ConcurrentExc);
-      int Thrd = FwkTest<TKey, TVal>.CurrentTest.GetUIntValue("numThreads");
-      Util.Log("EntryTask::DoTask: starting {0} iterations. and isSerialExecution is {1}", iters,isSerialExecution);
-      while (Running && (iters-- != 0))
-      {
-        if (isConcExecution && !m_finish)
-        {
-          doTransactions(m_region);
-        }
-        if (isSerialExecution && !m_finish)
-        {
-          lock (CLASS_LOCK)
-          {            
-           doSerialExecution(m_region);
-          }
-        }
-        if (m_finish && !m_commitTx)
-        {          
-          finishAllActiveTx(activeTxns,false);
-        }
-        if (m_beginTx)
-        {
-          lock (txlock)
-          {
-            TxInfo txInfo;
-            TransactionId txId = null;
-            txInfo = begin(m_region);
-            txId = (TransactionId)(object)txInfo.getTxId();
-            activeTxns[txId] = (Object)txInfo;
-          }
-        }
-
-        if (m_commitTx && m_finish)
-        {
-          finishAllActiveTx(activeTxns, m_commitTx);
-        }
-      }
-      Interlocked.Add(ref m_iters, count - offset);
-    }
-  }
-
-  public class ResumableTx<TKey,TVal> : FwkTest<TKey,TVal>
-  {
-    // Tx actions (for concurrent resumable transactions with function execution)
-    static protected int BEGIN_TX          = 1001;
-    static protected int EXECUTE_TX_OPS    = 1002;
-    static protected int EXECUTE_NONTX_OPS = 1003;
-    static protected int COMMIT            = 1004;
-    static protected int ROLLBACK          = 1005;
-    #region Private constants and statics
-
-    static protected int SUSPEND = 2;
-    static protected int RESUME = 3;
- 
-    private static Dictionary<string, Dictionary<TKey, TVal>> BeforeTxMap = new Dictionary<string, Dictionary<TKey, TVal>>();
-    private static Dictionary<string, Dictionary<TKey, TVal>> AfterTxMap = new Dictionary<string, Dictionary<TKey, TVal>>();
-    protected static Dictionary<TransactionId, object> activeTxns = null;
-    protected static Dictionary<IRegion<TKey,TVal>,Dictionary<TKey, TVal>> OpMap = null;
-    //private List<TransactionId> keyList;
-    //private static int globalTxId = 0;
-    //private static int ExecutionNo = 0;
-    //private static string RRName = null;
-       
-    private object CLASS_LOCK = new object();
-    
-    #endregion
-
-    private const string RegionName = "regionName";
-    private const string ValueSizes = "valueSizes";
-    private const string OpsSecond = "opsSecond";
-    private const string EntryCount = "entryCount";
-    private const string WorkTime = "workTime";
-    private const string EntryOps = "entryOps";
-    private const string LargeSetQuery = "largeSetQuery";
-    private const string UnsupportedPRQuery = "unsupportedPRQuery";
-    private const string ObjectType = "objectType";
-    protected const string NumThreads = "numThreads";
-    protected const string TimedInterval = "timedInterval";
-    protected const string DistinctKeys = "distinctKeys";
-    protected const string BEGINTX = "isBeginTX";
-    protected const string COMMITTX = "isCommitTX";
-
-    public class SilenceListener<TKey1, TVal1> : CacheListenerAdapter<TKey1,TVal1>
-    {
-      public override void AfterCreate(EntryEvent<TKey1, TVal1> ev)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("SilenceListener: AfterCreate key");
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("SilenceListener: AfterCreate key = {0} value = {1}", ev.Key, ev.NewValue);
-      }
-      public override void AfterUpdate(EntryEvent<TKey1, TVal1> ev)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("SilenceListener: AfterUpdate");
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("SilenceListener: AfterUpdate key = {0} value = {1}", ev.Key, ev.NewValue);
-      }
-      public override void AfterDestroy(EntryEvent<TKey1, TVal1> ev)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("SilenceListener: AfterDestroy");
-      }
-      public override void AfterInvalidate(EntryEvent<TKey1, TVal1> ev)
-      {
-        FwkTest<TKey, TVal>.CurrentTest.FwkInfo("SilenceListener: AfterInvalidate");
-      }
-    }
-
-    #region Private utility methods
-
-    private IRegion<TKey, TVal> GetRegion()
-    {
-      return GetRegion(null);
-    }
-
-    protected IRegion<TKey, TVal> GetRegion(string regionName)
-    {
-      IRegion<TKey, TVal> region;
-      if (regionName == null)
-      {
-        regionName = GetStringValue("regionName");
-      }
-      if (regionName == null)
-      {
-        region = (IRegion<TKey, TVal>)GetRootRegion();
-        if (region == null)
-        {
-          IRegion<TKey, TVal>[] rootRegions = CacheHelper<TKey, TVal>.DCache.RootRegions<TKey, TVal>();
-          if (rootRegions != null && rootRegions.Length > 0)
-          {
-            region = rootRegions[Util.Rand(rootRegions.Length)];
-          }
-        }
-      }
-      else
-      {
-        region = CacheHelper<TKey, TVal>.GetRegion(regionName);
-      }
-      return region;
-    }
-    #endregion
-
-    #region Public Methods
-
-    public static ICacheListener<TKey, TVal> CreateSilenceListener()
-    {
-      return new SilenceListener<TKey, TVal>();
-    }
-
-    public virtual void DoCreatePool()
-    {
-      FwkInfo("In DoCreatePool()");
-      try
-      {
-        CreatePool();
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoCreatePool() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoCreatePool() complete.");
-    }
-
-
-    public virtual void DoCreateRegion()
-    {
-      FwkInfo("ResumableTx:DoCreateRegion()");
-      try
-      {
-        IRegion<TKey, TVal> region = CreateRootRegion();
-        ResetKey("useTransactions");
-        if (region == null)
-        {
-          FwkException("ResumableTx:DoCreateRegion()  could not create region.");
-        }
-        FwkInfo("ResumableTx:DoCreateRegion()  Created region '{0}'", region.Name);
-      }
-      catch (Exception ex)
-      {
-        FwkException("ResumableTx:DoCreateRegion() Caught Exception: {0}", ex);
-      }
-      FwkInfo("ResumableTx:DoCreateRegion() complete.");
-    }
-
-    public void DoCloseCache()
-    {
-      FwkInfo("DoCloseCache()  Closing cache and disconnecting from" +
-        " distributed system.");
-      CacheHelper<TKey, TVal>.Close();
-    }
-
-    public void DoRegisterAllKeys()
-    {
-      FwkInfo("In DoRegisterAllKeys()");
-      try
-      {
-        IRegion<TKey, TVal> region = GetRegion();
-        FwkInfo("DoRegisterAllKeys() region name is {0}", region.Name);
-        bool isDurable = GetBoolValue("isDurableReg");
-        ResetKey("getInitialValues");
-        bool isGetInitialValues = GetBoolValue("getInitialValues");
-        bool checkReceiveVal = GetBoolValue("checkReceiveVal");
-        bool isReceiveValues = true;
-        if (checkReceiveVal)
-        {
-          ResetKey("receiveValue");
-          isReceiveValues = GetBoolValue("receiveValue");
-        }
-        region.GetSubscriptionService().RegisterAllKeys(isDurable, isGetInitialValues, isReceiveValues);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRegisterAllKeys() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRegisterAllKeys() complete.");
-    }
-
-    public void DoSerialTxWithOps()
-    {
-      FwkInfo("Inside DoSerialTxWithOps ActiveMap count is {0}", activeTxns.Count);
-      IRegion<TKey, TVal> region = GetRegion();
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-      OpMap = new Dictionary<IRegion<TKey, TVal>, Dictionary<TKey, TVal>>();
-
-      int timedInterval = GetTimeValue("timedInterval") * 1000;
-      int maxTime = 10 * timedInterval;
-      // Loop over key set sizes
-      ResetKey("distinctKeys");
-      int numKeys = GetUIntValue("distinctKeys");
-      
-      ResetKey(NumThreads);
-      int numThreads;
-      while ((numThreads = GetUIntValue(NumThreads)) > 0)
-      {
-        EntryTxTask<TKey, TVal> entrytask = new EntryTxTask<TKey, TVal>(region, numKeys / numThreads, activeTxns, OpMap,false,false,false);
-        FwkInfo("Running timed task ");
-        try
-        {
-          RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-        }
-        catch (ClientTimeoutException)
-        {
-          FwkException("In DoSerialTxWithOps()  Timed run timed out.");
-        }
-        FwkInfo("Completed timed task ");
-        Thread.Sleep(3000);
-        //entrytask.dumpToBB();
-      }
-    }
-
-    public void DoConcTxWithOps()
-    {
-      FwkInfo("Inside ResumableTx:DoConcTxWithOps()");
-      IRegion<TKey, TVal> region = GetRegion();
-      activeTxns = new Dictionary<TransactionId, object>();
-      OpMap = new Dictionary<IRegion<TKey, TVal>, Dictionary<TKey, TVal>>();
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 10 : secondsToRun;
-
-      DateTime now = DateTime.Now;
-      DateTime end = now.AddSeconds(secondsToRun);
-
-      int timedInterval = GetTimeValue(TimedInterval) * 1000;
-      int maxTime = 10 * timedInterval; 
-      // Loop over key set sizes
-      ResetKey(DistinctKeys);
-      int numKeys = GetUIntValue(DistinctKeys);
-
-      ResetKey(NumThreads);
-      int numThreads;
-      while ((numThreads = GetUIntValue(NumThreads)) > 0)
-      {
-        EntryTxTask<TKey, TVal> entrytask = new EntryTxTask<TKey, TVal>(region, numKeys / numThreads, activeTxns,OpMap,false,false,false);
-        FwkInfo("Running timed task ");
-        try
-        {
-          RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-        }
-        catch (ClientTimeoutException)
-        {
-          FwkException("In DoConcTxWithOps()  Timed run timed out.");
-        }
-        Thread.Sleep(3000);
-        //entrytask.dumpToBB();
-      }
-      FwkInfo("Completed timed task ");
-    }
-
-    public void DoBeginTx()
-    {
-      IRegion<TKey, TVal> region = GetRegion();
-      activeTxns = new Dictionary<TransactionId, object>();
-      int timedInterval = GetTimeValue(TimedInterval) * 1000;
-      int maxTime = 10 * timedInterval;
-      ResetKey(DistinctKeys);
-
-      ResetKey(BEGINTX);
-      bool isBeginTx = GetBoolValue(BEGINTX);
-     
-      int numKeys = GetUIntValue(DistinctKeys);
-       ResetKey(NumThreads);
-      int numThreads;
-      while ((numThreads = GetUIntValue(NumThreads)) > 0)
-      {
-        EntryTxTask<TKey, TVal> entrytask = new EntryTxTask<TKey, TVal>(region, numKeys / numThreads, activeTxns,OpMap, false, isBeginTx, false);
-        FwkInfo("Running timed task ");
-        try
-        {
-          RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-        }
-        catch (ClientTimeoutException)
-        {
-          FwkException("In DoBeginTx()  Timed run timed out.");
-        }
-        Thread.Sleep(3000);
-        //entrytask.dumpToBB();
-      }
-
-    }
-
-    public void DoFinishAllActiveTx()
-    {
-      FwkInfo("Inside DoFinishActiveTx ActiveMap count is {0}",activeTxns.Count);
-      Dictionary<TKey, TVal> tempmap = new Dictionary<TKey, TVal>();
-      IRegion<TKey, TVal> region = GetRegion();
-      int timedInterval = GetTimeValue(TimedInterval) * 1000;
-      int maxTime = 10 * timedInterval;
-      // Loop over key set sizes
-      ResetKey(DistinctKeys);
-      int numKeys = GetUIntValue(DistinctKeys);
-
-      ResetKey(COMMITTX);
-      bool isCommitTx = GetBoolValue(COMMITTX);
-      //bool Finish=true;
-      ResetKey(NumThreads);
-      int numThreads;
-      while ((numThreads = GetUIntValue(NumThreads)) > 0)
-      {
-        EntryTxTask<TKey, TVal> entrytask = new EntryTxTask<TKey, TVal>(region, numKeys / numThreads, activeTxns,OpMap, true,false,isCommitTx);
-        FwkInfo("Running timed task ");
-        try
-        {
-          RunTask(entrytask, numThreads, -1, timedInterval, maxTime, null);
-        }
-        catch (ClientTimeoutException)
-        {
-          FwkException("In DoFinishAllActiveTx()  Timed run timed out.");
-        }
-        Thread.Sleep(3000);
-        //entrytask.dumpToBB();
-      }
-
-    }
-
-    public void DoPopulateRegion() 
-    {
-      CacheTransactionManager txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager; 
-      //TransactionId txId = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager; 
-      IRegion<TKey, TVal> reg = GetRegion();
-      for (int i = 0; i < 5; i++)
-      {
-        TKey key = (TKey)(object)(i);
-        TVal value = (TVal)(object)"Value_";
-        txManager.Begin();
-        reg[key] = value;
-        txManager.Commit();
-        Util.Log("The Key is={0} and value={1}", key.ToString(), value.ToString());
-      }
-    }
-
-    public void DoGet()
-    {
-      IRegion<TKey, TVal> reg = GetRegion();
-      for (int i = 0; i < 5; i++)
-      {
-        TKey key = (TKey)(object)(i);
-        try
-        {
-          TVal val = reg[key];
-          Util.Log("The Key is={0} and value={1}", key.ToString(), val.ToString());
-        }
-        catch (Exception e) { FwkException("SP:Caught {0}",e); }
-      }
-    }
-
-    public void DoBasicTX()
-    {
-      FwkInfo("Inside ResumableTx:DoBasicTX()");
-      IRegion<TKey, TVal> region = GetRegion();
-      string opcode = null;
-      int action = 0;
-      int minNoEx = GetUIntValue("minExecutions");
-
-      if (region == null)
-      {
-        FwkSevere("ResumableTx:DoBasicTX(): No region to perform operations on.");
-      }
-      CacheTransactionManager txManager = null;
-      TransactionId txId = null;
-
-      int numOfEx = 0;
-      try
-      {
-        txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-        if (numOfEx == 0)
-        {
-          FwkInfo("Begin.() tx numOfEx={0} and minNoEx={1}", numOfEx, minNoEx);
-          txManager.Begin();
-          action = BEGIN_TX;
-          doValidateTxOps(txId, action);
-        }
-        while (!(numOfEx > minNoEx))
-        {
-          try
-          {
-            FwkInfo("numOfEx={0} and minNoEx={1}", numOfEx, minNoEx);
-            txId = txManager.Suspend();
-            action = SUSPEND;
-            doValidateTxOps(txId, action);
-
-            txManager.Resume(txId);
-            int numKeys = 100;
-            Dictionary<TKey, TVal> keyValMap = new Dictionary<TKey, TVal>();
-            TKey key;
-            TVal value;
-            for (int i = 0; i < numKeys; i++)
-            {
-              string keyName = String.Format("key_{0}", i);
-              key = (TKey)(object)keyName.ToString();
-              value = (TVal)(object)"Value_";
-              region[key] = value;
-              keyValMap[key] = value;
-              AfterTxMap["put"] = keyValMap;
-            }
-            action = RESUME;
-            FwkInfo("keyValMap count={0} and region count is {1}",keyValMap.Count,region.Keys.Count);
-            doValidateTxOps(txId, action);
-          }
-          catch (IllegalStateException ex)
-          {
-            FwkException("Got {0}", ex.Message);
-          }
-          catch (CommitConflictException ex)
-          {
-            FwkException("Got {0}", ex.Message);
-          }
-          numOfEx++;
-        }
-        if (numOfEx > minNoEx)
-        {
-          try
-          {
-            txManager.Commit();
-          }
-          catch (CommitConflictException)
-          {
-            FwkInfo("Got Expected exception as there was a write conflict");
-          }
-          action = COMMIT;
-          doValidateTxOps(txId, action);
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("ResumableTx.DoEntryOpsWithTX() Caught unexpected " +
-         "exception during entry '{0}' operation: {1}.", opcode, ex);
-      }
-    }
-
-    public void doValidateTxOps(TransactionId txId, int txState)
-    {
-      FwkInfo("Inside Resumabletx:DoValidateTxOps");
-      FwkInfo("Transactional Id is {0} and transaction state is={1}",txId,txState);
-      //int cnt =0;
-      //TKey key;
-      int txnState = txState;
-      TransactionId txnId = txId;
-      ResetKey("entryCount");
-      int EntryCount=GetUIntValue("entryCount");
-      CacheTransactionManager txManager = CacheHelper<TKey, TVal>.DCache.CacheTransactionManager;
-      try 
-      {
-        switch (txnState)
-        {
-          case 1001:
-            FwkInfo("...txnState is Begin ...");
-            checkContainsKey(txnState);
-            break;
-          case 2:
-            FwkInfo("...txnState is Suspend...");
-            if (!txManager.IsSuspended(txId) && !txManager.Exists(txId))
-            {
-              FwkException("After Suspend(),the Transaction should have been Suspended and should still exist");
-            }
-            checkContainsKey(txnState);
-            break;
-          case 3:
-            FwkInfo("...txnState is Resume...");
-            if (txManager.IsSuspended(txnId))
-            {
-              FwkException("After Resume(),the Transaction should NOT have been Suspended");
-            }
-            if (!txManager.Exists(txnId))
-            {
-              FwkException("After Resume(),the Transaction should still exist");
-            }
-            checkContainsKey(txnState);
-            break;
-          case 1004:
-            FwkInfo("...txnState is Commit...");
-            if (txManager.IsSuspended(txnId))
-            {
-              FwkException("After Commit(),the Transaction should NOT have been Suspended");
-            }
-            if (txManager.Exists(txnId))
-            {
-              FwkException("After Commit(),the Transaction should Not exist");
-            }
-            if (txManager.TryResume(txnId))
-            {
-              FwkException("After Commit(),the Transaction should Not be resumed");
-            }
-            checkContainsKey(txnState);
-            FwkInfo("Commit BeforeTxMap.Count={0} ", BeforeTxMap.Count);
-            break;
-        }
-
-      }
-      catch(Exception ex) 
-      {
-        FwkException("doValidateTxOps caught exception {0}",ex.Message);
-      }
-    }
-
-    public void checkContainsKey(int txnState)
-    {
-      IRegion<TKey, TVal> region = GetRegion();
-      Dictionary<TKey, TVal> BfTxOpMap = new Dictionary<TKey, TVal>();
-      Dictionary<TKey, TVal> AfTxOpMap = new Dictionary<TKey, TVal>();
-      try
-      {
-        if (txnState == 3)
-        {
-          BfTxOpMap = BeforeTxMap["put"];
-          AfTxOpMap = AfterTxMap["put"];
-        }
-        else
-          BfTxOpMap = BeforeTxMap["put"];
-        
-      }
-      catch (Exception e) 
-      {
-        FwkException("Throwing this exception {0} BMap cpunt={1} AfMap Count={2}", e.Message, BfTxOpMap.Count, AfTxOpMap.Count); 
-      }
-      FwkInfo("BfTxOpmap count is {0} and AfterTxMap is {1}", BfTxOpMap.Count, AfTxOpMap.Count);
-      foreach (KeyValuePair<TKey, TVal> bkp in BfTxOpMap)
-      {
-        FwkInfo("Inside BfTxOpMap");
-        TKey BfTxKey = bkp.Key;
-        if (!region.ContainsKey(BfTxKey))
-          FwkException("getKey: expected key {0} is not present in the region key set", bkp.Key.ToString());
-      }
-      foreach (KeyValuePair<TKey, TVal> akp in AfTxOpMap)
-      {
-        FwkInfo("Inside AfTxOpMap");
-        TKey AfTxKey = akp.Key;
-        if (!region.ContainsKey(AfTxKey))
-          FwkException("getKey: expected key {0} is not present in the region key set", akp.Key.ToString());
-      }
-    }
-
-   #endregion
-  }
-}
-
diff --git a/tests/cli/NewFwkLib/ResumableTx/TxInfo.cs b/tests/cli/NewFwkLib/ResumableTx/TxInfo.cs
deleted file mode 100644
index 97218b4..0000000
--- a/tests/cli/NewFwkLib/ResumableTx/TxInfo.cs
+++ /dev/null
@@ -1,168 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib  
-{
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-  
-
-//[Serializable]
-//  public class TxInfo<Tkey,TVal>
-//  {
-//    TransactionId txId;
-//    int numExecutions;
-//    String regionName;
-//    Object key;
-//    //ModRoutingObject routingObject;
-
-//    public TxInfo()
-//    {
-//      this.numExecutions = 0;
-//    }
-
-//    public String getTxId()
-//    {
-//      return this.txId;
-//    }
-
-//    public int getNumExecutions()
-//    {
-//      return this.numExecutions;
-//    }
-
-//    public String getRegionName()
-//    {
-//      return this.regionName;
-//    }
-
-//    public Object getKey()
-//    {
-//      return this.key;
-//    }
-
-//    //public ModRoutingObject getRoutingObject()
-//    //{
-//    //  return this.routingObject;
-//    //}
-
-//    public void setTxId(String txId)
-//    {
-//      this.txId = txId;
-//    }
-
-//    public void setNumExecutions(int executions)
-//    {
-//      this.numExecutions = executions;
-//    }
-
-//    public void incrementNumExecutions()
-//    {
-//      //this.numExecutions = numExecutions++;
-//      setNumExecutions(this.numExecutions++);
-//      Util.Log("Inside TXInfo numExecutionis {0}", this.numExecutions++);
-
-//    }
-
-//    public void setRegionName(String regionName)
-//    {
-//      this.regionName = regionName;
-//    }
-
-//    public void setKey(Object aKey)
-//    {
-//      this.key = aKey;
-//    }
-
-//    //public void setRoutingObject(ModRoutingObject aRoutingObject)
-//    //{
-//    //  this.routingObject = aRoutingObject;
-//    //}
-
-//    public String toString()
-//    {
-//      string aStr = "";
-//      //StringBuffer aStr = new StringBuffer();
-//      //aStr.append("TxInfo {" + txId + ", numExecutions: " + numExecutions + ", FilterInfo {" + regionName + ", " + key + ", " + routingObject + "}");
-//      return aStr;
-//    }
-//  }
-  [Serializable]
-  public class TxInfo //: IPdxSerializable
-  {
-    TransactionId txId;
-   // Object txId;
-    int numExecutions;
-    //String regionName;
-     
-    public TxInfo()
-     {
-       this.numExecutions = 0;
-     }
-
-    public TransactionId getTxId()
-    {
-      return this.txId;
-    }
-
-    //public Object getTxId()
-    //{
-    //  return this.txId;
-    //}
-     public int getNumExecutions()
-     {
-       return this.numExecutions;
-     }
-
-     //public String getRegionName()
-     //{
-     //  return this.regionName;
-     //}
-
-    public void setTxId(TransactionId txId)
-    {
-      this.txId = txId;
-    }
-
-    //public void setTxId(Object txId)
-    //{
-    //  this.txId = txId;
-    //}
-
-     public void setNumExecutions(int executions)
-     {
-       this.numExecutions = executions;
-     }
-
-     public void incrementNumExecutions()
-     {
-       //this.numExecutions = numExecutions++;
-       setNumExecutions(this.numExecutions++);
-       Util.Log("Inside TXInfo numExecutionis {0}", this.numExecutions++);
-
-     }
-  
-  }
-}
-
diff --git a/tests/cli/NewFwkLib/SecurityTest/Security.cs b/tests/cli/NewFwkLib/SecurityTest/Security.cs
deleted file mode 100644
index fcafd5a..0000000
--- a/tests/cli/NewFwkLib/SecurityTest/Security.cs
+++ /dev/null
@@ -1,518 +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.
- */
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.DUnitFramework;
-
-  public class Security : PerfTests
-  {
-
-    #region Protected constants
-
-    protected const string EntryCount = "entryCount";
-    protected const string WorkTime = "workTime";
-    protected const string ObjectType = "objectType";
-    protected const string EntryOps = "entryOps";
-    protected const string LargeSetQuery = "largeSetQuery";
-    protected const string UnsupportedPRQuery = "unsupportedPRQuery";
-
-    #endregion
-
-    #region Utility methods
-
-    private CacheableKey GetKey(int max)
-    {
-      ResetKey(ObjectType);
-      string objectType = GetStringValue(ObjectType);
-      QueryHelper qh = QueryHelper.GetHelper();
-      int numSet = 0;
-      int setSize = 0;
-      if (objectType != null && objectType == "Portfolio")
-      {
-        setSize = qh.PortfolioSetSize;
-        numSet = max / setSize;
-        return new CacheableString(String.Format("port{0}-{1}",
-          Util.Rand(numSet), Util.Rand(setSize)));
-      }
-      else if (objectType != null && objectType == "Position")
-      {
-        setSize = qh.PositionSetSize;
-        numSet = max / setSize;
-        return new CacheableString(String.Format("pos{0}-{1}",
-          Util.Rand(numSet), Util.Rand(setSize)));
-      }
-      else
-      {
-        return m_keysA[Util.Rand(m_maxKeys)];
-      }
-    }
-
-    private ISerializable GetUserObject(string objType)
-    {
-      ISerializable usrObj = null;
-      ResetKey(EntryCount);
-      int numOfKeys = GetUIntValue(EntryCount);
-      ResetKey(ValueSizes);
-      int objSize = GetUIntValue(ValueSizes);
-      QueryHelper qh = QueryHelper.GetHelper();
-      int numSet = 0;
-      int setSize = 0;
-      if (objType != null && objType == "Portfolio")
-      {
-        setSize = qh.PortfolioSetSize;
-        numSet = numOfKeys / setSize;
-        usrObj = new Portfolio(Util.Rand(setSize), objSize);
-      }
-      else if (objType != null && objType == "Position")
-      {
-        setSize = qh.PositionSetSize;
-        numSet = numOfKeys / setSize;
-        int numSecIds = Portfolio.SecIds.Length;
-        usrObj = new Position(Portfolio.SecIds[setSize % numSecIds], setSize * 100);
-      }
-      return usrObj;
-    }
-
-    private bool AllowQuery(QueryCategory category, bool haveLargeResultset,
-      bool islargeSetQuery, bool isUnsupportedPRQuery)
-    {
-      if (category == QueryCategory.Unsupported)
-      {
-        return false;
-      }
-      else if (haveLargeResultset != islargeSetQuery)
-      {
-        return false;
-      }
-      else if (isUnsupportedPRQuery &&
-               ((category == QueryCategory.MultiRegion) ||
-                (category == QueryCategory.NestedQueries)))
-      {
-        return false;
-      }
-      else
-      {
-        return true;
-      }
-    }
-
-    private void RunQuery(ref int queryCnt)
-    {
-      FwkInfo("In Security.RunQuery");
-
-      try
-      {
-        ResetKey(EntryCount);
-        int numOfKeys = GetUIntValue(EntryCount);
-        QueryHelper qh = QueryHelper.GetHelper();
-        int setSize = qh.PortfolioSetSize;
-        if (numOfKeys < setSize)
-        {
-          setSize = numOfKeys;
-        }
-        int index = Util.Rand(QueryStrings.RSsize);
-        DateTime startTime;
-        DateTime endTime;
-        TimeSpan elapsedTime;
-        QueryService qs = CacheHelper<TKey, TVal>.DCache.GetQueryService();
-        ResetKey(LargeSetQuery);
-        ResetKey(UnsupportedPRQuery);
-        bool isLargeSetQuery = GetBoolValue(LargeSetQuery);
-        bool isUnsupportedPRQuery = GetBoolValue(UnsupportedPRQuery);
-        QueryStrings currentQuery = QueryStatics.ResultSetQueries[index];
-        if (AllowQuery(currentQuery.Category, currentQuery.IsLargeResultset,
-            isLargeSetQuery, isUnsupportedPRQuery))
-        {
-          string query = currentQuery.Query;
-          FwkInfo("Security.RunQuery: ResultSet Query Category [{0}], " +
-            "String [{1}].", currentQuery.Category, query);
-          Query qry = qs.NewQuery(query);
-          startTime = DateTime.Now;
-          ISelectResults results = qry.Execute(600);
-          endTime = DateTime.Now;
-          elapsedTime = endTime - startTime;
-          FwkInfo("Security.RunQuery: Time Taken to execute" +
-            " the query [{0}]: {1}ms", query, elapsedTime.TotalMilliseconds);
-          ++queryCnt;
-        }
-        index = Util.Rand(QueryStrings.SSsize);
-        currentQuery = QueryStatics.StructSetQueries[index];
-        if (AllowQuery(currentQuery.Category, currentQuery.IsLargeResultset,
-            isLargeSetQuery, isUnsupportedPRQuery))
-        {
-          string query = currentQuery.Query;
-          FwkInfo("Security.RunQuery: StructSet Query Category [{0}], " +
-            "String [{1}].", currentQuery.Category, query);
-          Query qry = qs.NewQuery(query);
-          startTime = DateTime.Now;
-          ISelectResults results = qry.Execute(600);
-          endTime = DateTime.Now;
-          elapsedTime = endTime - startTime;
-          FwkInfo("Security.RunQuery: Time Taken to execute" +
-            " the query [{0}]: {1}ms", query, elapsedTime.TotalMilliseconds);
-          ++queryCnt;
-        }
-      }
-      catch (Exception ex)
-      {
-        FwkException("Security.RunQuery: Caught Exception: {0}", ex);
-      }
-      FwkInfo("Security.RunQuery complete.");
-    }
-
-    #endregion
-
-    #region Public methods
-
-    public new void DoRegisterInterestList()
-    {
-      FwkInfo("In DoRegisterInterestList()");
-      try
-      {
-        Region region = GetRegion();
-        int numKeys = GetUIntValue(DistinctKeys);  // check distince keys first
-        if (numKeys <= 0)
-        {
-          FwkSevere("DoRegisterInterestList() Failed to initialize keys " +
-            "with numKeys: {0}", numKeys);
-          return;
-        }
-        int low = GetUIntValue(KeyIndexBegin);
-        low = (low > 0) ? low : 0;
-        int numOfRegisterKeys = GetUIntValue(RegisterKeys);
-        int high = numOfRegisterKeys + low;
-        ClearKeys();
-        m_maxKeys = numOfRegisterKeys;
-        m_keyIndexBegin = low;
-        int keySize = GetUIntValue(KeySize);
-        keySize = (keySize > 0) ? keySize : 10;
-        string keyBase = new string('A', keySize);
-        InitStrKeys(low, high, keyBase);
-
-        FwkInfo("DoRegisterInterestList() registering interest for {0} to {1}",
-          low, high);
-        CacheableKey[] registerKeyList = new CacheableKey[high - low];
-        for (int j = low; j < high; j++)
-        {
-          if (m_keysA[j - low] != null)
-          {
-            registerKeyList[j - low] = m_keysA[j - low];
-          }
-          else
-          {
-            FwkInfo("DoRegisterInterestList() key[{0}] is null.", (j - low));
-          }
-        }
-        FwkInfo("DoRegisterInterestList() region name is {0}", region.Name);
-        region.RegisterKeys(registerKeyList);
-      }
-      catch (Exception ex)
-      {
-        FwkException("DoRegisterInterestList() Caught Exception: {0}", ex);
-      }
-      FwkInfo("DoRegisterInterestList() complete.");
-    }
-
-    public void DoEntryOperations()
-    {
-      FwkInfo("DoEntryOperations called.");
-
-      int opsSec = GetUIntValue(OpsSecond);
-      opsSec = (opsSec < 1) ? 0 : opsSec;
-
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-      int valSize = GetUIntValue(ValueSizes);
-      valSize = ((valSize < 0) ? 32 : valSize);
-
-      DateTime now = DateTime.Now;
-      DateTime end = now + TimeSpan.FromSeconds(secondsToRun);
-
-      byte[] valBuf = Encoding.ASCII.GetBytes(new string('A', valSize));
-
-      string opcode = null;
-
-      int creates = 0, puts = 0, gets = 0, dests = 0, invals = 0, queries = 0;
-      Region region = GetRegion();
-      if (region == null)
-      {
-        FwkSevere("Security.DoEntryOperations: No region to perform operations on.");
-        now = end; // Do not do the loop
-      }
-
-      FwkInfo("DoEntryOperations will work for {0} secs using {1} byte values.", secondsToRun, valSize);
-
-      CacheableKey key;
-      ISerializable value;
-      ISerializable tmpValue;
-      PaceMeter meter = new PaceMeter(opsSec);
-      string objectType = GetStringValue(ObjectType);
-      while (now < end)
-      {
-        try
-        {
-          opcode = GetStringValue(EntryOps);
-          if (opcode == null || opcode.Length == 0) opcode = "no-op";
-
-          if (opcode == "add")
-          {
-            key = GetKey(entryCount);
-            if (objectType != null && objectType.Length > 0)
-            {
-              tmpValue = GetUserObject(objectType);
-            }
-            else
-            {
-              tmpValue = CacheableBytes.Create(valBuf);
-            }
-            region.Create(key, tmpValue);
-            creates++;
-          }
-          else
-          {
-            key = GetKey(entryCount);
-            if (opcode == "update")
-            {
-              if (objectType != null && objectType.Length > 0)
-              {
-                tmpValue = GetUserObject(objectType);
-              }
-              else
-              {
-                int keyVal = int.Parse(key.ToString());
-                int val = BitConverter.ToInt32(valBuf, 0);
-                val = (val == keyVal) ? keyVal + 1 : keyVal;  // alternate the value so that it can be validated later.
-                BitConverter.GetBytes(val).CopyTo(valBuf, 0);
-                BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-                tmpValue = CacheableBytes.Create(valBuf);
-              }
-              region.Put(key, tmpValue);
-              puts++;
-            }
-            else if (opcode == "invalidate")
-            {
-              region.Invalidate(key);
-              invals++;
-            }
-            else if (opcode == "destroy")
-            {
-              region.Destroy(key);
-              dests++;
-            }
-            else if (opcode == "read")
-            {
-              value = region.Get(key);
-              gets++;
-            }
-            else if (opcode == "read+localdestroy")
-            {
-              value = region.Get(key);
-              gets++;
-              region.LocalDestroy(key);
-              dests++;
-            }
-            else if (opcode == "query")
-            {
-              RunQuery(ref queries);
-            }
-            else
-            {
-              FwkSevere("Invalid operation specified: {0}", opcode);
-            }
-          }
-        }
-        catch (TimeoutException ex)
-        {
-          FwkSevere("Security: Caught unexpected timeout exception during entry " +
-            "{0} operation; continuing with the test: {1}", opcode, ex);
-        }
-        catch (EntryExistsException)
-        {
-        }
-        catch (EntryNotFoundException)
-        {
-        }
-        catch (EntryDestroyedException)
-        {
-        }
-        catch (Exception ex)
-        {
-          end = DateTime.Now;
-          FwkException("Security: Caught unexpected exception during entry " +
-            "{0} operation; exiting task: {1}", opcode, ex);
-        }
-        meter.CheckPace();
-        now = DateTime.Now;
-      }
-      FwkInfo("DoEntryOperations did {0} creates, {1} puts, {2} gets, " +
-        "{3} invalidates, {4} destroys, {5} queries.", creates, puts, gets,
-        invals, dests, queries);
-    }
-
-    public void DoEntryOperationsMU()
-    {
-      FwkInfo("DoEntryOperations called.");
-
-      int opsSec = GetUIntValue(OpsSecond);
-      opsSec = (opsSec < 1) ? 0 : opsSec;
-
-      int entryCount = GetUIntValue(EntryCount);
-      entryCount = (entryCount < 1) ? 10000 : entryCount;
-
-      int secondsToRun = GetTimeValue(WorkTime);
-      secondsToRun = (secondsToRun < 1) ? 30 : secondsToRun;
-
-      int valSize = GetUIntValue(ValueSizes);
-      valSize = ((valSize < 0) ? 32 : valSize);
-
-      DateTime now = DateTime.Now;
-      DateTime end = now + TimeSpan.FromSeconds(secondsToRun);
-
-      byte[] valBuf = Encoding.ASCII.GetBytes(new string('A', valSize));
-
-      string opcode = null;
-
-      int creates = 0, puts = 0, gets = 0, dests = 0, invals = 0, queries = 0;
-      Region region = GetRegion();
-      if (region == null)
-      {
-        FwkSevere("Security.DoEntryOperations: No region to perform operations on.");
-        now = end; // Do not do the loop
-      }
-
-      FwkInfo("DoEntryOperations will work for {0} secs using {1} byte values.", secondsToRun, valSize);
-
-      CacheableKey key;
-      ISerializable value;
-      ISerializable tmpValue;
-      PaceMeter meter = new PaceMeter(opsSec);
-      string objectType = GetStringValue(ObjectType);
-      while (now < end)
-      {
-        try
-        {
-          opcode = GetStringValue(EntryOps);
-          if (opcode == null || opcode.Length == 0) opcode = "no-op";
-
-          if (opcode == "add")
-          {
-            key = GetKey(entryCount);
-            if (objectType != null && objectType.Length > 0)
-            {
-              tmpValue = GetUserObject(objectType);
-            }
-            else
-            {
-              tmpValue = CacheableBytes.Create(valBuf);
-            }
-            region.Create(key, tmpValue);
-            creates++;
-          }
-          else
-          {
-            key = GetKey(entryCount);
-            if (opcode == "update")
-            {
-              if (objectType != null && objectType.Length > 0)
-              {
-                tmpValue = GetUserObject(objectType);
-              }
-              else
-              {
-                int keyVal = int.Parse(key.ToString());
-                int val = BitConverter.ToInt32(valBuf, 0);
-                val = (val == keyVal) ? keyVal + 1 : keyVal;  // alternate the value so that it can be validated later.
-                BitConverter.GetBytes(val).CopyTo(valBuf, 0);
-                BitConverter.GetBytes(DateTime.Now.Ticks).CopyTo(valBuf, 4);
-                tmpValue = CacheableBytes.Create(valBuf);
-              }
-              region.Put(key, tmpValue);
-              puts++;
-            }
-            else if (opcode == "invalidate")
-            {
-              region.Invalidate(key);
-              invals++;
-            }
-            else if (opcode == "destroy")
-            {
-              region.Destroy(key);
-              dests++;
-            }
-            else if (opcode == "read")
-            {
-              value = region.Get(key);
-              gets++;
-            }
-            else if (opcode == "read+localdestroy")
-            {
-              value = region.Get(key);
-              gets++;
-              region.LocalDestroy(key);
-              dests++;
-            }
-            else if (opcode == "query")
-            {
-              RunQuery(ref queries);
-            }
-            else
-            {
-              FwkSevere("Invalid operation specified: {0}", opcode);
-            }
-          }
-        }
-        catch (TimeoutException ex)
-        {
-          FwkSevere("Security: Caught unexpected timeout exception during entry " +
-            "{0} operation; continuing with the test: {1}", opcode, ex);
-        }
-        catch (EntryExistsException)
-        {
-        }
-        catch (EntryNotFoundException)
-        {
-        }
-        catch (EntryDestroyedException)
-        {
-        }
-        catch (Exception ex)
-        {
-          end = DateTime.Now;
-          FwkException("Security: Caught unexpected exception during entry " +
-            "{0} operation; exiting task: {1}", opcode, ex);
-        }
-        meter.CheckPace();
-        now = DateTime.Now;
-      }
-      FwkInfo("DoEntryOperations did {0} creates, {1} puts, {2} gets, " +
-        "{3} invalidates, {4} destroys, {5} queries.", creates, puts, gets,
-        invals, dests, queries);
-    }
-    #endregion
-  }
-}
diff --git a/tests/cli/NewFwkLib/Utils.cs b/tests/cli/NewFwkLib/Utils.cs
deleted file mode 100644
index 54213e0..0000000
--- a/tests/cli/NewFwkLib/Utils.cs
+++ /dev/null
@@ -1,1457 +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.
- */
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Text.RegularExpressions;
-using System.Threading;
-
-namespace Apache.Geode.Client.FwkLib
-{
-
-  using Apache.Geode.DUnitFramework;
-  using Apache.Geode.Client.Tests;
-  using Apache.Geode.Client;
-  using NEWAPI = Apache.Geode.Client.Tests;
-  [Serializable]
-  struct HostInfo
-  {
-    public bool Started;
-    public string HostType;
-    public string HostName;
-    public string ExtraServerArgs;
-
-    public HostInfo(bool started, string hostType, string hostName,
-      string extraServerArgs)
-    {
-      Started = started;
-      HostType = hostType;
-      HostName = hostName;
-      ExtraServerArgs = extraServerArgs;
-    }
-  }
-
-  public class Utils<TKey, TVal> : FwkTest<TKey, TVal>
-  {
-    private const char PathSep = '/';
-    private const int MaxWaitMillis = 1800000;
-    private const string SetupJSName = "setupJavaServers";
-    private const string StartJSName = "startJavaServers";
-    private const string StopJSName = "stopJavaServers";
-    private const string KillJSName = "killJavaServers";
-    private const string SleepTime = "sleepTime";
-    private const string MinServers = "minServers";
-    private const string JavaServerCountKey = "ServerCount";
-    private const string JavaServerMapKey = "ServerMap";
-    private const string JavaServerName = "cacheserver.bat";
-    private const string JavaServerOtherArgs =
-      " statistic-sampling-enabled=true" +
-      " statistic-archive-file=statArchive.gfs mcast-port=0";
-    private const string JavaServerJavaArgs =
-      " -J-Xmx1280m -J-Xms512m -J-DCacheClientProxy.MESSAGE_QUEUE_SIZE=100000";
-    private const string JavaServerJavaArgsUnix =
-      " -J-Xmx2048m -J-Xms1024m -J-XX:+HeapDumpOnOutOfMemoryError " +
-      "-J-DCacheClientProxy.MESSAGE_QUEUE_SIZE=100000";
-    private static string TempDir = Util.GetEnvironmentVariable("TMP");
-    // Constants for status
-    private const int GFNoError = 0;
-    private const int GFError = 1;
-    private const int GFTimeout = 2;
-
-    private static Dictionary<string, HostInfo> m_javaServerHostMap =
-      new Dictionary<string, HostInfo>();
-    private static int m_numServers = 1;
-    private static int locCount = 0;
-    private static volatile bool m_exiting = false;
-    private static bool m_firstRun = true;
-    private static string m_locatorHost = null;
-    private static string m_locatorType = null;
-
-    #region Private methods
-
-    private string[] ParseJavaServerArgs(string argStr, ref int numServers,
-      out int argIndx, out string extraServerArgs)
-    {
-      argIndx = 0;
-      extraServerArgs = string.Empty;
-      if (argStr != null && argStr.Length > 0)
-      {
-        string[] args = argStr.Split(' ');
-        while (args.Length > argIndx && args[argIndx][0] == '-')
-        {
-          FwkAssert(args.Length > (argIndx + 1),
-            "JavaServer() value not provided after option '{0}'.",
-            args[argIndx]);
-          string argName = args[argIndx];
-          string argValue = args[argIndx + 1];
-          switch (argName)
-          {
-            case "-t":
-              // Ignore the tagname; we now use the hostGroup name as the tag
-              break;
-            case "-N":
-              break;
-            case "-M":
-              break;
-            case "-X":
-              break;
-            case "-c":
-              numServers = int.Parse(argValue);
-              break;
-            case "-e":
-              // @TODO: this is C++ specific environment variables -- ignored for now
-              break;
-            case "-p":
-              extraServerArgs += (" " + argValue.Replace("\\", "").
-                Replace("\"", "").Replace("'", ""));
-              break;
-            default:
-              FwkException("JavaServer() Unknown option '{0}'", argName);
-              break;
-          }
-          argIndx += 2;
-        }
-        extraServerArgs += " ";
-        return args;
-      }
-      return new string[0];
-    }
-
-    private string GetHostGroup()
-    {
-      string hostGroup;
-      try
-      {
-        hostGroup = Util.BBGet(Util.ClientId,
-          FwkReadData.HostGroupKey) as string;
-      }
-      catch
-      {
-        hostGroup = null;
-      }
-      return (hostGroup == null ? string.Empty : hostGroup);
-    }
-
-    private static HostInfo GetHostInfo(string serverId)
-    {
-      HostInfo hostInfo = new HostInfo();
-      lock (((ICollection)m_javaServerHostMap).SyncRoot)
-      {
-        if (m_javaServerHostMap.Count == 0)
-        {
-          try
-          {
-            m_javaServerHostMap = Util.BBGet(JavaServerBB, JavaServerMapKey)
-              as Dictionary<string, HostInfo>;
-          }
-          catch
-          {
-          }
-        }
-        if (m_javaServerHostMap.ContainsKey(serverId))
-        {
-          hostInfo = m_javaServerHostMap[serverId];
-        }
-      }
-      return hostInfo;
-    }
-
-    private static string GetJavaStartDir(string serverId, string hostType)
-    {
-      return Util.GetLogBaseDir(hostType) + PathSep + "GFECS_" + serverId;
-    }
-    private static string GetLocatorStartDir(string locatorId, string hostType)
-    {
-      return Util.GetLogBaseDir(hostType) + PathSep + "GFELOC_" + locatorId;
-    }
-    private string GetJavaLocator()
-    {
-      try
-      {
-        return (string)Util.BBGet(string.Empty, "LOCATOR_ADDRESS");
-      }
-      catch
-      {
-        return null;
-      }
-    }
-    private string GetJavaLocatorForPoolAttri()
-    {
-      try
-      {
-        return (string)Util.BBGet(string.Empty, "LOCATOR_ADDRESS_POOL");
-      }
-      catch
-      {
-        return null;
-      }
-    }
-    private bool GetSetJavaLocator(string locatorHost,
-      out int locatorPort)
-    {
-      locatorPort = 0;
-      string locatorAddress = GetJavaLocator();
-      string locatorAddressForPool = GetJavaLocatorForPoolAttri();
-      if (locatorAddress == null || locatorAddress.Length == 0)
-      {
-        locatorPort = Util.Rand(31124, 54343);
-        locatorAddress = locatorHost + '[' + locatorPort + ']';
-        locatorAddressForPool = locatorHost + ':' + locatorPort;
-        Util.BBSet(string.Empty, "LOCATOR_ADDRESS", locatorAddress);
-        Util.BBSet(string.Empty, "LOCATOR_ADDRESS_POOL", locatorAddressForPool);
-        locCount++;
-        return true;
-      }
-      if (locatorAddress != null && locatorAddress.Length > 0 && locCount > 0)
-      {
-        locatorPort = Util.Rand(31124, 54343);
-        locatorAddress += ',' + locatorHost + '[' + locatorPort + ']';
-        locatorAddressForPool += ',' + locatorHost + ':' + locatorPort;
-        Util.BBSet(string.Empty, "LOCATOR_ADDRESS", locatorAddress);
-        Util.BBSet(string.Empty, "LOCATOR_ADDRESS_POOL", locatorAddressForPool);
-        locCount++;
-        return true;
-      }
-      return false;
-    }
-
-    private static int StartLocalGFExe(string exeName, string gfeDir,
-      string exeArgs, out string outStr)
-    {
-      int status = GFNoError;
-      Process javaProc;
-      string javaExePath = gfeDir + PathSep + "bin" + PathSep + exeName;
-      Util.ServerLog("Executing local Geode command {0} {1}", javaExePath,
-        exeArgs);
-      if (!Util.StartProcess(javaExePath, exeArgs, false, TempDir,
-        true, false, false, out javaProc))
-      {
-        outStr = null;
-        return GFError;
-      }
-
-      StreamReader outSr = javaProc.StandardOutput;
-      // Wait for process to start
-      bool started = javaProc.WaitForExit(MaxWaitMillis);
-      outStr = outSr.ReadLine();
-      outSr.Close();
-      if (!started)
-      {
-        try
-        {
-          javaProc.Kill();
-        }
-        catch
-        {
-        }
-        status = GFTimeout;
-      }
-      else if (javaProc.ExitCode != 0)
-      {
-        status = GFError;
-      }
-      return status;
-    }
-
-    private static string StartRemoteGFExe(string host, string hostType,
-      string exeName, string exeArgs)
-    {
-      string gfJavaDir = Util.GetEnvironmentVariable("GFE_DIR", hostType);
-      string gfClassPath = Util.GetEnvironmentVariable("CLASSPATH", hostType);
-      string gfJava = Util.GetEnvironmentVariable("GF_JAVA", hostType);
-
-      string javaCmd = gfJavaDir + "/bin/" + exeName + ' ' + exeArgs;
-      Dictionary<string, string> envVars = new Dictionary<string, string>();
-      if (gfClassPath != null && gfClassPath.Length > 0)
-      {
-        envVars["CLASSPATH"] = gfClassPath;
-      }
-      if (gfJava != null && gfJava.Length > 0)
-      {
-        envVars["GF_JAVA"] = gfJava;
-      }
-      return Util.RunClientShellTask(Util.ClientId, host, javaCmd, envVars);
-    }
-
-    private string GetWorkerId(string serverNum)
-    {
-      return "worker." + serverNum;
-    }
-
-    private string CreateWorkerTaskSpecification(string progName,
-      string serverNum, string extraArgs)
-    {
-      extraArgs = (extraArgs == null ? string.Empty : ' ' + extraArgs);
-      return string.Format("<task name=\"Deleg{1}\" action=\"doRunProcess\" " +
-        "container=\"utils\" waitTime=\"25m\">{0}<data name=\"program\">" +
-        "{1}</data>{0}" + "<data name=\"arguments\">{2}{3}</data>{0}" +
-        "<client-set name=\"{4}\">{0}<client name=\"{5}\"/>{0}" +
-        "</client-set>{0}</task>", Environment.NewLine, progName, serverNum,
-        extraArgs, Util.ClientId, GetWorkerId(serverNum));
-    }
-    private string GetSslProperty(string hostType, bool forServer,string startDir)
-    {
-      string sslCmdStr = null;
-      //if (!File.Exists(startDir + PathSep + "geode.properties"))
-      //{
-        TextWriter sw = new StreamWriter(startDir + PathSep + "geode.properties", false);
-        String locatorAddress = GetJavaLocator();
-        sw.WriteLine("locators={0}", locatorAddress);
-        ResetKey("sslEnable");
-        bool isSslEnable = GetBoolValue("sslEnable");
-        if (!isSslEnable)
-        {
-          sw.Close();
-          return string.Empty;
-        }
-        FwkInfo("ssl is enable");
-        if (!forServer)
-        {
-          //StreamWriter sw = new StreamWriter("geode.properties",false);
-          sw.WriteLine("ssl-enabled=true");
-          sw.WriteLine("ssl-require-authentication=true");
-          sw.WriteLine("mcast-port=0");
-          sw.WriteLine("ssl-ciphers=SSL_RSA_WITH_NULL_SHA");
-        }
-
-        sw.Close();
-
-        string keyStorePath = Util.GetFwkLogDir(hostType) + "/data/keystore/sslcommon.jks";
-        string trustStorePath = Util.GetFwkLogDir(hostType) + "/data/keystore/server_truststore.jks";
-        sslCmdStr = " -Djavax.net.ssl.keyStore=" + keyStorePath +
-          " -Djavax.net.ssl.keyStorePassword=gemstone -Djavax.net.ssl.trustStore=" + trustStorePath +
-          " -Djavax.net.ssl.trustStorePassword=gemstone";
-        //string securityParams = GetStringValue(SecurityParams);
-        if (forServer)
-        {
-          sslCmdStr = " -J-Djavax.net.ssl.keyStore=" + keyStorePath +
-            " -J-Djavax.net.ssl.keyStorePassword=gemstone -J-Djavax.net.ssl.trustStore=" + trustStorePath +
-            " -J-Djavax.net.ssl.trustStorePassword=gemstone " +
-            " ssl-enabled=true  ssl-require-authentication=true ssl-ciphers=SSL_RSA_WITH_NULL_SHA";
-        }
-      //}
-      return sslCmdStr;
-    }
-    private string GetServerSecurityArgs(string hostType)
-    {
-      string securityParams = GetStringValue(SecurityParams);
-      CredentialGenerator gen;
-      // no security means security params is not applicable
-      if (securityParams == null || securityParams.Length == 0 ||
-        (gen = GetCredentialGenerator()) == null)
-      {
-        FwkInfo("Security is DISABLED.");
-        return string.Empty;
-      }
-      string logDir = Util.GetFwkLogDir(hostType);
-      if (logDir == null || logDir.Length == 0)
-      {
-        logDir = Util.GetLogBaseDir(hostType);
-        logDir = logDir.Substring(0, logDir.LastIndexOf("/"));
-        logDir = logDir.Substring(0, logDir.LastIndexOf("/"));
-      }
-      string dataDir = logDir + "/data";
-      gen.Init(dataDir, dataDir);
-      Properties<string,string> extraProps = new Properties<string,string>();
-      if (gen.SystemProperties != null)
-      {
-        extraProps.AddAll(gen.SystemProperties);
-      }
-      // For now only XML based authorization is supported
-      AuthzCredentialGenerator authzGen = new XmlAuthzCredentialGenerator();
-      authzGen.Init(gen);
-      if (authzGen.SystemProperties != null)
-      {
-        extraProps.AddAll(authzGen.SystemProperties);
-      }
-      return Utility.GetServerArgs(gen.Authenticator,
-        authzGen.AccessControl, null, extraProps, gen.JavaProperties);
-    }
-
-    private void SetupJavaServers(string argStr)
-    {
-      int argIndx;
-      string endpoints = string.Empty;
-      m_numServers = 1;
-
-      string gfeDir = Util.GetEnvironmentVariable("GFE_DIR");
-
-      FwkAssert(gfeDir != null && gfeDir.Length != 0,
-        "SetupJavaServers() GFE_DIR is not set.");
-
-      string hostGroup = GetHostGroup();
-      Match mt;
-
-      if (argStr == "CPP")
-      {
-        // special string to denote that endpoints have to be obtained
-        // from C++ framework
-        string fwkBBPath = Util.AssemblyDir + "/../../bin/FwkBB";
-        string fwkBBArgs = "getInt GFE_BB EP_COUNT";
-        Process fwkBBProc;
-        if (!Util.StartProcess(fwkBBPath, fwkBBArgs, false, null,
-          true, false, false, out fwkBBProc))
-        {
-          FwkException("SetupJavaServers() Cannot start C++ FwkBB [{0}].",
-            fwkBBPath);
-        }
-        int numEndpoints = int.Parse(fwkBBProc.StandardOutput.ReadToEnd());
-        fwkBBProc.WaitForExit();
-        fwkBBProc.StandardOutput.Close();
-        for (int index = 1; index <= numEndpoints; index++)
-        {
-          fwkBBArgs = "get GFE_BB EndPoints_" + index;
-          if (!Util.StartProcess(fwkBBPath, fwkBBArgs, false, null,
-            true, false, false, out fwkBBProc))
-          {
-            FwkException("SetupJavaServers() Cannot start C++ FwkBB [{0}].",
-              fwkBBPath);
-          }
-          string endpoint = fwkBBProc.StandardOutput.ReadToEnd();
-          fwkBBProc.WaitForExit();
-          fwkBBProc.StandardOutput.Close();
-          if (endpoints.Length > 0)
-          {
-            endpoints += ',' + endpoint;
-          }
-          else
-          {
-            endpoints = endpoint;
-          }
-        }
-      }
-      else if ((mt = Regex.Match(gfeDir, "^[^:]+:[0-9]+(,[^:]+:[0-9]+)*$"))
-        != null && mt.Length > 0)
-      {
-        // The GFE_DIR is for a remote server; contains an end-point list
-        endpoints = gfeDir;
-      }
-      else
-      {
-        string extraServerArgs;
-        string[] args = ParseJavaServerArgs(argStr, ref m_numServers,
-          out argIndx, out extraServerArgs);
-        Util.BBSet(JavaServerBB, FwkTest<TKey,TVal>.JavaServerEPCountKey, m_numServers);
-        FwkAssert(args.Length == argIndx + 1, "SetupJavaServers() cache XML argument not correct");
-        string cacheXml = args[argIndx];
-        FwkAssert(cacheXml.Length > 0, "SetupJavaServers() cacheXml argument is empty.");
-
-        string xmlDir = Util.GetEnvironmentVariable("GFBASE") + "/framework/xml";
-        if (xmlDir != null && xmlDir.Length > 0)
-        {
-          cacheXml = Util.NormalizePath(xmlDir + PathSep + cacheXml);
-        }
-
-        int javaServerPort = Util.GetAvailablePort();
-
-        List<string> targetHosts = Util.BBGet(FwkReadData.HostGroupKey,
-          hostGroup) as List<string>;
-        for (int serverNum = 1; serverNum <= m_numServers; serverNum++)
-        {
-          if (m_exiting)
-          {
-            return;
-          }
-          string serverId = hostGroup + '_' + serverNum;
-          string startDir = GetJavaStartDir(serverId, Util.SystemType);
-          if (!Directory.Exists(startDir))
-          {
-            Directory.CreateDirectory(startDir);
-          }
-
-          string targetHost;
-          int numHosts = (targetHosts == null ? 0 : targetHosts.Count);
-          int lruMemSizeMb = 700;
-          if (numHosts == 0)
-          {
-            targetHost = Util.HostName;
-            lock (((IDictionary)m_javaServerHostMap).SyncRoot)
-            {
-              m_javaServerHostMap[serverId] = new HostInfo();
-            }
-          }
-          else
-          {
-            int hostIndex;
-            if (numHosts > 1)
-            {
-              hostIndex = ((serverNum - 1) % (numHosts - 1)) + 1;
-            }
-            else
-            {
-              hostIndex = 0;
-            }
-            targetHost = targetHosts[hostIndex];
-            FwkInfo("Checking the type of host {0}.", targetHost);
-            string hostType = Util.RunClientShellTask(Util.ClientId,
-              targetHost, "uname", null);
-            hostType = Util.GetHostType(hostType);
-            FwkInfo("The host {0} is: {1}", targetHost, hostType);
-            if (hostType != "WIN")
-            {
-              lruMemSizeMb = 1400;
-            }
-            lock (((IDictionary)m_javaServerHostMap).SyncRoot)
-            {
-              m_javaServerHostMap[serverId] = new HostInfo(false,
-                hostType, targetHost, extraServerArgs);
-            }
-          }
-          // Create the cache.xml with correct port
-          javaServerPort++;
-          StreamReader cacheXmlReader = new StreamReader(cacheXml);
-          string cacheXmlContent = cacheXmlReader.ReadToEnd();
-          cacheXmlReader.Close();
-          cacheXmlContent = cacheXmlContent.Replace("$PORT_NUM",
-            javaServerPort.ToString()).Replace("$LRU_MEM",
-            lruMemSizeMb.ToString());
-          StreamWriter cacheXmlWriter = new StreamWriter(startDir +
-            PathSep + "cache.xml");
-          cacheXmlWriter.Write(cacheXmlContent);
-          cacheXmlWriter.Close();
-
-          Util.ServerLog("SetupJavaServers() added '{0}' for host '{1}'",
-            serverId, targetHost);
-          FwkInfo("SetupJavaServers() added '{0}' for host '{1}'",
-            serverId, targetHost);
-
-          if (serverNum == 1)
-          {
-            endpoints = targetHost + ':' + javaServerPort;
-          }
-          else
-          {
-            endpoints += ',' + targetHost + ':' + javaServerPort;
-          }
-          Util.BBSet(JavaServerBB, FwkTest<TKey,TVal>.EndPoints + "_" + serverNum.ToString(), targetHost + ':' + javaServerPort);
-        }
-
-
-        int[] locatorPort = new int[2];
-        int locatorPort1;
-        HostInfo locatorInfo = GetHostInfo(hostGroup + "_1");
-        string locatorHost = locatorInfo.HostName;
-        string locatorType = locatorInfo.HostType;
-        if (locatorHost == null)
-        {
-          locatorHost = Util.HostName;
-          locatorType = Util.SystemType;
-        }
-        if (locatorType == Util.SystemType)
-        {
-          locatorHost = Util.HostName;
-        }
-        //ResetKey("multiLocator");
-        //bool isMultiLocator = GetBoolValue("multiLocator");
-        //if (isMultiLocator)
-        //{
-        for (int i = 0; i < 2; i++)
-        {
-          GetSetJavaLocator(locatorHost, out locatorPort1);
-          locatorPort[i] = locatorPort1;
-        }
-        for (int i = 0; i < 2; i++)
-        {
-          //if (GetSetJavaLocator(locatorHost, out locatorPort))
-          //{
-          FwkInfo("SetupJavaServers() starting locator on host {0}",
-            locatorHost);
-
-          string locatorDir = GetLocatorStartDir((i + 1).ToString(), Util.SystemType);
-          if (!Directory.Exists(locatorDir))
-          {
-            Directory.CreateDirectory(locatorDir);
-          }
-          ResetKey("sslEnable");
-          bool isSslEnable = GetBoolValue("sslEnable");
-          /*
-          if (isSslEnable)
-          {
-            locatorDir = locatorDir + "/..";
-          }
-          */
-          string sslArg = GetSslProperty(locatorType, false, locatorDir);
-          locatorDir = GetLocatorStartDir((i + 1).ToString(), locatorType);
-            FwkInfo("ssl arguments: {0} {1}", sslArg, locatorDir);
-            string locatorArgs = "start-locator -port=" + locatorPort[i] +
-              " -dir=" + locatorDir + sslArg;
-            if (locatorType != Util.SystemType)
-            {
-              FwkInfo(StartRemoteGFExe(locatorHost, locatorType,
-                "geode", locatorArgs));
-            }
-            else
-            {
-              string outStr;
-              int status = StartLocalGFExe("geode.bat", gfeDir,
-                locatorArgs, out outStr);
-              if (status == GFTimeout)
-              {
-                FwkException("SetupJavaServers() Timed out while starting " +
-                  "locator. Please check the logs in {0}", locatorDir);
-              }
-              else if (status != GFNoError)
-              {
-                FwkException("SetupJavaServers() Error while starting " +
-                  "locator. Please check the logs in {0}", locatorDir);
-              }
-              FwkInfo(outStr);
-            }
-
-            if (isSslEnable)
-            {
-              Util.RegisterTestCompleteDelegate(TestCompleteWithSSL);
-            }
-            else
-            {
-              Util.RegisterTestCompleteDelegate(TestCompleteWithoutSSL);
-            }
-            m_locatorHost = locatorHost;
-            m_locatorType = locatorType;
-            FwkInfo("SetupJavaServers() started locator on host {0}.",
-              locatorHost);
-          //}
-        }
-        //}
-      }
-      FwkInfo("SetupJavaServers() endpoints: {0}", endpoints);
-      // Write the endpoints for both the tag and the cumulative one
-      string globalEndPoints;
-      try
-      {
-        globalEndPoints = Util.BBGet(string.Empty,
-          FwkTest<TKey, TVal>.EndPointTag) as string;
-      }
-      catch (Apache.Geode.DUnitFramework.KeyNotFoundException)
-      {
-        globalEndPoints = null;
-      }
-      if (globalEndPoints != null && globalEndPoints.Length > 0 &&
-        endpoints != null && endpoints.Length > 0)
-      {
-        globalEndPoints += ',' + endpoints;
-      }
-      else
-      {
-        globalEndPoints = endpoints;
-      }
-      Util.BBSet(JavaServerBB, FwkTest<TKey, TVal>.EndPointTag, globalEndPoints);
-      Util.BBSet(JavaServerBB, FwkTest<TKey, TVal>.EndPointTag + hostGroup, endpoints);
-      lock (((IDictionary)m_javaServerHostMap).SyncRoot)
-      {
-        Util.BBSet(JavaServerBB, JavaServerMapKey, m_javaServerHostMap);
-      }
-      FwkInfo("SetupJavaServers() completed.");
-    }
-
-    private void StartJavaServers(string argStr)
-    {
-      int numServers = -1;
-      int argIndx;
-      string extraServerArgs;
-      string[] args = ParseJavaServerArgs(argStr, ref numServers,
-        out argIndx, out extraServerArgs);
-
-      string gfeDir = Util.GetEnvironmentVariable("GFE_DIR");
-      string endpoints = string.Empty;
-      string locatorAddress = GetJavaLocator();
-
-      FwkAssert(gfeDir != null && gfeDir.Length != 0,
-        "StartJavaServers() GFE_DIR is not set.");
-      FwkAssert(locatorAddress != null && locatorAddress.Length > 0,
-        "StartJavaServers() LOCATOR_ADDRESS is not set.");
-
-      string hostGroup = GetHostGroup();
-
-      Match mt = Regex.Match(gfeDir, "^[^:]+:[0-9]+(,[^:]+:[0-9]+)*$");
-      if (mt == null || mt.Length == 0)
-      {
-        int startServer = 1;
-        int endServer;
-        if (args.Length == (argIndx + 1))
-        {
-          startServer = int.Parse(args[argIndx]);
-          endServer = (numServers == -1 ? startServer :
-            (startServer + numServers - 1));
-        }
-        else
-        {
-          endServer = (numServers == -1 ? m_numServers : numServers);
-        }
-        for (int serverNum = startServer; serverNum <= endServer; serverNum++)
-        {
-          if (m_exiting)
-          {
-            break;
-          }
-          string serverId = hostGroup + '_' + serverNum;
-          HostInfo hostInfo = GetHostInfo(serverId);
-          string targetHost = hostInfo.HostName;
-          string hostType = hostInfo.HostType;
-          string startDir = GetJavaStartDir(serverId, hostType);
-          extraServerArgs = hostInfo.ExtraServerArgs + ' ' + extraServerArgs;
-          string sslArg = GetSslProperty(hostType, true, startDir);
-          FwkInfo("ssl arguments for server: {0} ",sslArg);
-          string javaServerOtherArgs = GetServerSecurityArgs(hostType) + ' ' + sslArg;
-          if (javaServerOtherArgs != null && javaServerOtherArgs.Length > 0)
-          {
-            FwkInfo("StartJavaServers() Using security server args: {0}",
-              javaServerOtherArgs);
-          }
-          javaServerOtherArgs = JavaServerOtherArgs + ' ' + javaServerOtherArgs;
-          if (targetHost == null || targetHost.Length == 0 ||
-            Util.IsHostMyself(targetHost))
-          {
-            string cacheXml = startDir + PathSep + "cache.xml";
-            string javaServerArgs = "start" + JavaServerJavaArgs + " -dir=" +
-              startDir + " cache-xml-file=" + cacheXml + " locators=" +
-              locatorAddress + extraServerArgs + javaServerOtherArgs ;
-
-            // Assume the GFE_DIR is for starting a local server
-            FwkInfo("StartJavaServers() starting {0} with GFE_DIR {1} " +
-              "and arguments: {2}", JavaServerName, gfeDir, javaServerArgs);
-            string outStr;
-            int status = StartLocalGFExe(JavaServerName, gfeDir,
-              javaServerArgs, out outStr);
-            if (status == GFTimeout)
-            {
-              FwkException("StartJavaServers() Timed out waiting for Java " +
-                "cacheserver to start. Please check the server log in {0}.",
-                startDir);
-            }
-            else if (status != GFNoError)
-            {
-              FwkSevere("StartJavaServers() Error in starting Java " +
-                "cacheserver. Please check the server log in {0}.", startDir);
-              Thread.Sleep(60000);
-            }
-            FwkInfo("StartJavaServers() output from start script: {0}",
-              outStr);
-          }
-          else if (hostType != Util.SystemType)
-          {
-            FwkInfo("StartJavaServers() starting '{0}' on remote host " +
-              "'{1}' of type {2}", serverId, targetHost, hostType);
-
-            string javaCSArgs = "start" +
-              JavaServerJavaArgsUnix + " -dir=" + startDir +
-              " cache-xml-file=cache.xml locators=" + locatorAddress +
-              extraServerArgs + javaServerOtherArgs;
-            FwkInfo(StartRemoteGFExe(targetHost, hostType,
-              "cacheserver", javaCSArgs));
-          }
-          else
-          {
-            string taskSpec = CreateWorkerTaskSpecification(
-              "startJavaServers", serverNum.ToString(), null);
-            FwkInfo("StartJavaServers() starting '{0}' on host '{1}'",
-              serverId, targetHost);
-            Util.BBSet(Util.ClientId + '.' + GetWorkerId(
-              serverNum.ToString()), FwkReadData.HostGroupKey,
-              hostGroup);
-            if (!Util.RunClientWinTask(Util.ClientId, targetHost, taskSpec))
-            {
-              FwkException("StartJavaServers() failed to start '{0}' on host '{1}'",
-                serverId, targetHost);
-            }
-          }
-          lock (((IDictionary)m_javaServerHostMap).SyncRoot)
-          {
-            hostInfo.Started = true;
-            m_javaServerHostMap[serverId] = hostInfo;
-          }
-          Util.ServerLog("StartJavaServers() started '{0}' on host '{1}'",
-            serverId, targetHost);
-        }
-      }
-      ResetKey("sslEnable");
-      bool isSslEnabled = GetBoolValue("sslEnable");
-      if (isSslEnabled)
-      {
-        Util.RegisterTestCompleteDelegate(TestCompleteWithSSL);
-      }
-      else
-      {
-        Util.RegisterTestCompleteDelegate(TestCompleteWithoutSSL);
-      }
-      FwkInfo("StartJavaServers() completed.");
-    }
-
-    private void StopJavaServers(string argStr)
-    {
-      string gfeDir = Util.GetEnvironmentVariable("GFE_DIR");
-
-      FwkAssert(gfeDir != null && gfeDir.Length != 0,
-        "StopJavaServers() GFE_DIR is not set.");
-
-      Match mt = Regex.Match(gfeDir, "^[^:]+:[0-9]+(,[^:]+:[0-9]+)*$");
-      if (mt == null || mt.Length == 0)
-      {
-        int numServers = -1;
-        int argIndx;
-        string extraServerArgs;
-        string[] args = ParseJavaServerArgs(argStr, ref numServers,
-          out argIndx, out extraServerArgs);
-
-        string hostGroup = GetHostGroup();
-        string javaServerPath = gfeDir + PathSep + "bin" +
-          PathSep + JavaServerName;
-        // Assume the GFE_DIR is for stopping a local server
-        int startServer = 1;
-        int endServer;
-        if (args.Length == (argIndx + 1))
-        {
-          startServer = int.Parse(args[argIndx]);
-          endServer = (numServers == -1 ? startServer :
-            (startServer + numServers - 1));
-        }
-        else
-        {
-          endServer = (numServers == -1 ? m_numServers : numServers);
-        }
-        for (int serverNum = startServer; serverNum <= endServer; serverNum++)
-        {
-          if (m_exiting)
-          {
-            break;
-          }
-          string serverId = hostGroup + '_' + serverNum;
-          HostInfo hostInfo = GetHostInfo(serverId);
-          string targetHost = hostInfo.HostName;
-          string hostType = hostInfo.HostType;
-          string startDir = GetJavaStartDir(serverId, hostType);
-          string javaServerArgs = "stop -dir=" + startDir;
-          if (targetHost == null || targetHost.Length == 0 ||
-            Util.IsHostMyself(targetHost))
-          {
-            FwkInfo("StopJavaServers() stopping {0} with GFE_DIR {1} " +
-              "and arguments: {2}", JavaServerName, gfeDir, javaServerArgs);
-
-            string outStr;
-            int status = StartLocalGFExe(JavaServerName, gfeDir,
-              javaServerArgs, out outStr);
-            if (status != GFNoError)
-            {
-              if (status == GFTimeout)
-              {
-                FwkSevere("StopJavaServers() Timed out waiting for Java " +
-                  "cacheserver to stop. Please check the server log in {0}.",
-                  startDir);
-              }
-              else
-              {
-                Thread.Sleep(20000);
-              }
-              KillLocalJavaServer(serverId, "-9");
-            }
-          }
-          else if (hostType != Util.SystemType)
-          {
-            FwkInfo("StopJavaServers() stopping '{0}' on remote host " +
-              "'{1}' of type {2}", serverId, targetHost, hostType);
-            FwkInfo(StartRemoteGFExe(targetHost, hostType,
-              "cacheserver", javaServerArgs));
-          }
-          else
-          {
-            string taskSpec = CreateWorkerTaskSpecification(
-              "stopJavaServers", serverNum.ToString(), null);
-            FwkInfo("StopJavaServers() stopping '{0}' on host '{1}'",
-              serverId, targetHost);
-            if (!Util.RunClientWinTask(Util.ClientId, targetHost, taskSpec))
-            {
-              FwkSevere("StopJavaServers() failed to stop '{0}' on host '{1}'",
-                serverId, targetHost);
-            }
-            FwkInfo("StopJavaServers() stopped '{0}' on host '{1}'",
-              serverId, targetHost);
-          }
-          lock (((ICollection)m_javaServerHostMap).SyncRoot)
-          {
-            hostInfo.Started = false;
-            m_javaServerHostMap[serverId] = hostInfo;
-          }
-          Util.ServerLog("StopJavaServers() stopped '{0}' on host '{1}'",
-            serverId, targetHost);
-        }
-      }
-      FwkInfo("StopJavaServers() completed.");
-    }
-
-    private void KillJavaServers(string argStr)
-    {
-      string gfeDir = Util.GetEnvironmentVariable("GFE_DIR");
-
-      FwkAssert(gfeDir != null && gfeDir.Length != 0,
-        "KillJavaServers() GFE_DIR is not set.");
-
-      Match mt = Regex.Match(gfeDir, "^[^:]+:[0-9]+(,[^:]+:[0-9]+)*$");
-      if (mt == null || mt.Length == 0)
-      {
-        int numServers = -1;
-        int argIndx;
-        string extraServerArgs;
-        string[] args = ParseJavaServerArgs(argStr, ref numServers,
-          out argIndx, out extraServerArgs);
-
-        string hostGroup = GetHostGroup();
-        string javaServerPath = gfeDir + PathSep + "bin" +
-          PathSep + JavaServerName;
-        // Assume the GFE_DIR is for stopping a local server
-        int startServer = 1;
-        int endServer;
-        string signal = "15";
-        if (args.Length >= (argIndx + 1))
-        {
-          startServer = int.Parse(args[argIndx++]);
-          endServer = (numServers == -1 ? startServer :
-            (startServer + numServers - 1));
-          if (args.Length >= (argIndx + 1))
-          {
-            signal = args[argIndx];
-          }
-        }
-        else
-        {
-          endServer = (numServers == -1 ? m_numServers : numServers);
-        }
-        for (int serverNum = startServer; serverNum <= endServer; serverNum++)
-        {
-          if (m_exiting)
-          {
-            break;
-          }
-          string serverId = hostGroup + '_' + serverNum;
-          HostInfo hostInfo = GetHostInfo(serverId);
-          string targetHost = hostInfo.HostName;
-          string hostType = hostInfo.HostType;
-          if (targetHost == null || targetHost.Length == 0 ||
-            Util.IsHostMyself(targetHost))
-          {
-            FwkInfo("KillJavaServers() killing '{0}' on localhost", serverId);
-            KillLocalJavaServer(serverId, '-' + signal);
-          }
-          else if (hostType != Util.SystemType)
-          {
-            FwkInfo("KillJavaServers() killing '{0}' on remote host " +
-              "'{1}' of type {2}", serverId, targetHost, hostType);
-            string startDir = GetJavaStartDir(serverId, hostType);
-            string killCmd = '"' + Util.GetFwkLogDir(hostType) +
-              "/data/killJavaServer.sh\" " + signal + " \"" + startDir + '"';
-            FwkInfo(Util.RunClientShellTask(Util.ClientId, targetHost,
-              killCmd, null));
-          }
-          else
-          {
-            string taskSpec = CreateWorkerTaskSpecification(
-              "killJavaServers", serverNum.ToString(), signal);
-            FwkInfo("KillJavaServers() killing '{0}' on host '{1}'",
-              serverId, targetHost);
-            if (!Util.RunClientWinTask(Util.ClientId, targetHost, taskSpec))
-            {
-              FwkSevere("KillJavaServers() failed to kill '{0}' on host '{1}'",
-                serverId, targetHost);
-            }
-          }
-          lock (((ICollection)m_javaServerHostMap).SyncRoot)
-          {
-            hostInfo.Started = false;
-            m_javaServerHostMap[serverId] = hostInfo;
-          }
-          Util.ServerLog("KillJavaServers() killed '{0}' on host '{1}'",
-            serverId, targetHost);
-        }
-      }
-      FwkInfo("KillJavaServers() completed.");
-    }
-
-    private static string GetGFJavaPID(string javaLog)
-    {
-      string javaPID = null;
-      bool islocator = javaLog.Contains("locator.log");
-      using (FileStream fs = new FileStream(javaLog, FileMode.Open,
-        FileAccess.Read, FileShare.ReadWrite))
-      {
-        StreamReader sr = new StreamReader(fs);
-        Regex pidRE = new Regex(@"Process ID: [\s]*(?<PID>[^\s]*)",
-          RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
-        while (!sr.EndOfStream)
-        {
-          Match mt = pidRE.Match(sr.ReadLine());
-          if (mt != null && mt.Length > 0)
-          {
-            javaPID = mt.Groups["PID"].Value;
-            if(!islocator)
-              break;
-          }
-        }
-        sr.Close();
-        fs.Close();
-      }
-      return javaPID;
-    }
-
-    private static string GetJavaServerPID(string serverId)
-    {
-      string startDir = GetJavaStartDir(serverId, Util.SystemType);
-      string javaLog = startDir + "/cacheserver.log";
-      return GetGFJavaPID(javaLog);
-    }
-
-    private static bool KillLocalGFJava(string javaPID, string signal)
-    {
-      try
-      {
-        Process.GetProcessById(int.Parse(javaPID)).Kill();
-        return true;
-      }
-      catch (Exception excp)
-      {
-        LogException("KillLocalGFJava: {0}: {1}", excp.GetType().Name, excp.Message);
-        return false;
-      }
-    }
-
-    private static bool KillLocalGFJava_disabled(string javaPID, string signal)
-    {
-      bool success = false;
-      if (javaPID != null)
-      {
-        Process javaProc;
-        if (!Util.StartProcess("/bin/kill", "-f " + signal + ' ' + javaPID,
-          false, TempDir, false, false, false, out javaProc))
-        {
-          LogException("KillLocalGFJava(): unable to run 'kill'");
-        }
-
-        // Wait for java process to stop
-        bool stopped = javaProc.WaitForExit(MaxWaitMillis);
-        if (!stopped)
-        {
-          try
-          {
-            javaProc.Kill();
-          }
-          catch
-          {
-          }
-          LogSevere("KillLocalGFJava() Could not execute " +
-            "kill successfully.");
-        }
-        int numTries = 30;
-        while (numTries-- > 0)
-        {
-          if (!Util.StartProcess("/bin/kill", "-f -0 " + javaPID,
-            false, TempDir, false, false, false, out javaProc))
-          {
-            LogException("KillLocalGFJava(): unable to run 'kill'");
-          }
-          stopped = javaProc.WaitForExit(MaxWaitMillis);
-          if (stopped && javaProc.ExitCode == 0)
-          {
-            success = true;
-            break;
-          }
-          Thread.Sleep(10000);
-        }
-      }
-      return success;
-    }
-
-    private static void KillLocalJavaServer(string serverId, string signal)
-    {
-      string javaPID = GetJavaServerPID(serverId);
-      LogInfo("KillLocalJavaServer() killing '{0}' with PID '{1}' using " +
-        "signal '{2}'", serverId, javaPID, signal);
-      if (KillLocalGFJava(javaPID, signal))
-      {
-        string startDir = GetJavaStartDir(serverId, Util.SystemType);
-        File.Delete(startDir + "/.cacheserver.ser");
-      }
-      else
-      {
-        LogException("KillLocalJavaServer() Timed out waiting for " +
-          "Java cacheserver to stop.");
-      }
-    }
-
-    #endregion
-
-    #region Public methods loaded by XMLs
-
-    /// <summary>
-    /// Will run a process using Cygwin bash
-    /// </summary>
-    public void DoRunProcess()
-    {
-      string progName = GetStringValue("program");
-      
-      //bool driverUsingpsexec = false;
-      bool hostIsWindows = false;
-      try
-      {
-        //driverUsingpsexec = (bool)Util.BBGet(string.Empty, "UsePsexec");
-        hostIsWindows = (bool)Util.BBGet(string.Empty, Util.HostName + ".IsWindows");
-      }
-      catch
-      {
-      }
-      
-      if (progName == null)
-      {
-        FwkException("DoRunProcess(): program not specified for task {0}.",
-          TaskName);
-      }
-      string args = GetStringValue("arguments");
-      
-      if (progName == "cp") // for smpke perf xml
-      {
-        if (hostIsWindows )//&& driverUsingpsexec)
-          progName = "copy";
-        
-        string[] argStr = args.Split(' ');
-        int i = argStr[0].IndexOf("/framework/xml/");
-        string gfBaseDir = Util.GetEnvironmentVariable("GFBASE");
-        string sharePath = Util.NormalizePath(gfBaseDir);
-        string specName = argStr[0].Substring(i);
-        string perfStatictic = sharePath + specName;
-        args = perfStatictic + ' ' + (string)Util.BBGet(string.Empty,"XMLLOGDIR") + '/' + argStr[1];
-      }
-      string fullProg = progName + ' ' + args;
-      fullProg = fullProg.Trim();
-
-      // Special treatment for java server scripts since they are C++ specific
-      // (e.g. the environment variables they require, the FwkBBClient program,
-      //  the auto-ssh ...)
-      string[] progs = fullProg.Split(';');
-      for (int index = 0; index < progs.Length; index++)
-      {
-        if (m_exiting)
-        {
-          break;
-        }
-        string prog = progs[index].Trim();
-        int javaIndx;
-        if ((javaIndx = prog.IndexOf(SetupJSName)) >= 0)
-        {
-          args = prog.Substring(javaIndx + SetupJSName.Length).Trim();
-          SetupJavaServers(args);
-        }
-        else if ((javaIndx = prog.IndexOf(StartJSName)) >= 0)
-        {
-          args = prog.Substring(javaIndx + StartJSName.Length).Trim();
-          StartJavaServers(args);
-        }
-        else if ((javaIndx = prog.IndexOf(StopJSName)) >= 0)
-        {
-          args = prog.Substring(javaIndx + StopJSName.Length).Trim();
-          StopJavaServers(args);
-        }
-        else if ((javaIndx = prog.IndexOf(KillJSName)) >= 0)
-        {
-          args = prog.Substring(javaIndx + KillJSName.Length).Trim();
-          KillJavaServers(args);
-        }
-        else
-        {
-          FwkInfo("DoRunProcess() starting '{0}' using bash", prog);
-          
-          Process runProc = new Process();
-          ProcessStartInfo startInfo; 
-          
-          if (hostIsWindows)// && driverUsingpsexec)
-          {
-            prog = prog.Replace('/', '\\');
-            startInfo = new ProcessStartInfo("cmd",
-               string.Format("/C \"{0}\"", prog));
-          }
-          else
-            startInfo = new ProcessStartInfo("bash",
-              string.Format("-c \"{0}\"", prog));
-              
-          startInfo.CreateNoWindow = true;
-          startInfo.UseShellExecute = false;
-          startInfo.RedirectStandardOutput = true;
-          startInfo.RedirectStandardError = true;
-          runProc.StartInfo = startInfo;
-
-          if (!runProc.Start())
-          {
-            FwkException("DoRunProcess() unable to run '{0}' using bash", prog);
-          }
-          StreamReader outSr = runProc.StandardOutput;
-          StreamReader errSr = runProc.StandardError;
-          string outStr = outSr.ReadToEnd();
-          string errStr = errSr.ReadToEnd();
-          runProc.WaitForExit();
-          errSr.Close();
-          outSr.Close();
-
-          if (outStr != null && outStr.Length > 0)
-          {
-            FwkInfo("DoRunProcess() Output from executing '{0}':" +
-              "{1}{2}{3}{4}", prog, Environment.NewLine, outStr,
-              Environment.NewLine, Util.MarkerString);
-          }
-          if (errStr != null && errStr.Length > 0)
-          {
-            FwkSevere("DoRunProcess() Error output from executing '{0}':" +
-              "{1}{2}{3}{4}", prog, Environment.NewLine, errStr,
-              Environment.NewLine, Util.MarkerString);
-          }
-          FwkInfo("DoRunProcess() completed '{0}'.", prog);
-        }
-      }
-    }
-
-    public void DoSleep()
-    {
-      int secs = GetUIntValue(SleepTime);
-      if (secs < 1)
-      {
-        secs = 30;
-      }
-      FwkInfo("DoSleep() called for task: '{0}', sleeping for {1} seconds.",
-        TaskName, secs);
-      Thread.Sleep(secs * 1000);
-    }
-
-    public void DoRunProcessAndSleep()
-    {
-      DoRunProcess();
-      if (!m_exiting)
-      {
-        int secs = GetUIntValue(SleepTime);
-        if (secs > 0)
-        {
-          Thread.Sleep(secs * 1000);
-        }
-      }
-    }
-
-    public void DoStopStartServer()
-    {
-      if (m_firstRun)
-      {
-        m_firstRun = false;
-        Util.BBIncrement(JavaServerBB, JavaServerCountKey);
-      }
-
-      string op = GetStringValue("operation");
-      if (op == null || op.Length == 0)
-      {
-        FwkException("DoStopStartServer(): operation not specified.");
-      }
-      string serverId = GetStringValue("ServerId");
-      if (serverId == null || serverId.Length == 0)
-      {
-        FwkException("DoStopStartServer(): server id not specified.");
-      }
-      FwkInfo("DoStopStartServer(): stopping and starting server {0}.",
-        serverId);
-
-      UnitFnMethod<string> stopDeleg = null;
-      string stopArg = null;
-      if (op == "stop")
-      {
-        stopDeleg = StopJavaServers;
-        stopArg = serverId;
-      }
-      else if (op == "term")
-      {
-        stopDeleg = KillJavaServers;
-        stopArg = serverId;
-      }
-      else if (op == "kill")
-      {
-        stopDeleg = KillJavaServers;
-        stopArg = serverId + " 9";
-      }
-      else
-      {
-        FwkException("DoStopStartServer(): unknown operation {0}.", op);
-      }
-
-      int secs = GetUIntValue(SleepTime);
-      int minServers = GetUIntValue(MinServers);
-      minServers = (minServers <= 0) ? 1 : minServers;
-      FwkInfo("DoStopStartServer(): using minServers: {0}", minServers);
-      bool done = false;
-      while (!done)
-      {
-        int numServers = Util.BBDecrement(JavaServerBB, JavaServerCountKey);
-        if (numServers >= minServers)
-        {
-          stopDeleg(stopArg);
-          Thread.Sleep(60000);
-          StartJavaServers(serverId);
-          Thread.Sleep(60000);
-          Util.BBIncrement(JavaServerBB, JavaServerCountKey);
-          done = true;
-        }
-        else
-        {
-          Util.BBIncrement(JavaServerBB, JavaServerCountKey);
-          Thread.Sleep(1000);
-        }
-      }
-      if (secs > 0)
-      {
-        Thread.Sleep(secs * 1000);
-      }
-    }
-
-    #endregion
-
-    public static void TestCompleteWithSSL()
-    {
-      TestComplete(true);
-    }
-
-    public static void TestCompleteWithoutSSL()
-    {
-      TestComplete(false);
-    }
-
-    public static void TestComplete(bool ssl)
-    {
-      m_exiting = true;
-      lock (((ICollection)m_javaServerHostMap).SyncRoot)
-      {
-        if (m_javaServerHostMap.Count == 0)
-        {
-          try
-          {
-            m_javaServerHostMap = Util.BBGet(JavaServerBB, JavaServerMapKey)
-              as Dictionary<string, HostInfo>;
-          }
-          catch
-          {
-          }
-        }
-        if (m_javaServerHostMap.Count > 0)
-        {
-          // Stop all the remaining java servers here.
-          string gfeDir = Util.GetEnvironmentVariable("GFE_DIR");
-
-          LogAssert(gfeDir != null, "ClientExit() GFE_DIR is not set.");
-          LogAssert(gfeDir.Length != 0, "ClientExit() GFE_DIR is not set.");
-
-          Match mt = Regex.Match(gfeDir, "^[^:]+:[0-9]+(,[^:]+:[0-9]+)*$");
-          if (mt == null || mt.Length == 0)
-          {
-            foreach (KeyValuePair<string, HostInfo> serverHostPair
-              in m_javaServerHostMap)
-            {
-              string serverId = serverHostPair.Key;
-              string targetHost = serverHostPair.Value.HostName;
-              string hostType = serverHostPair.Value.HostType;
-              string startDir = GetJavaStartDir(serverId, hostType);
-              string javaServerArgs = "stop -dir=" + startDir;
-              if (serverHostPair.Value.Started)
-              {
-                if (targetHost == null || targetHost.Length == 0 ||
-                    Util.IsHostMyself(targetHost))
-                {
-                  LogInfo("ClientExit() stopping {0} with GFE_DIR {1} and " +
-                    "arguments: {2}", JavaServerName, gfeDir, javaServerArgs);
-
-                  string outStr;
-                  int status = StartLocalGFExe(JavaServerName, gfeDir,
-                    javaServerArgs, out outStr);
-                  if (status != GFNoError)
-                  {
-                    if (status == GFTimeout)
-                    {
-                      LogSevere("ClientExit() Timed out waiting for Java " +
-                        "cacheserver to stop. Please check the server log " +
-                        "in {0}.", startDir);
-                    }
-                    KillLocalJavaServer(serverId, "-9");
-                  }
-                }
-                else if (hostType != Util.SystemType)
-                {
-                  // Stop the remote host
-                  LogInfo("ClientExit() stopping '{0}' on remote host " +
-                    "'{1}' of type {2}", serverId, targetHost, hostType);
-                  LogInfo(StartRemoteGFExe(targetHost, hostType,
-                    "cacheserver", javaServerArgs));
-                }
-              }
-            }
-          }
-          m_javaServerHostMap.Clear();
-        }
-        // Stop the locator here.
-        if (m_locatorHost != null && m_locatorType != null)
-        {
-          LogInfo("ClientExit() stopping locator on host {0}", m_locatorHost);
-          for (int i = 0; i < locCount; i++)
-          {
-            string locatorDir = GetLocatorStartDir((i + 1).ToString(), Util.SystemType);
-            /* if (ssl)
-            {
-              locatorDir = locatorDir + "/..";
-            }
-            */
-          string locatorPID = GetGFJavaPID(locatorDir +
-            PathSep + "locator.log");
-          if (locatorPID != null && locatorPID.Length > 0)
-          {
-            if (m_locatorType != Util.SystemType)
-            {
-              string killCmd = "kill -15 " + locatorPID;
-              LogInfo(Util.RunClientShellTask(Util.ClientId, m_locatorHost,
-                killCmd, null));
-              Thread.Sleep(3000);
-              killCmd = "kill -9 " + locatorPID;
-              LogInfo(Util.RunClientShellTask(Util.ClientId, m_locatorHost,
-                killCmd, null));
-              LogInfo("ClientExit() successfully stopped locator PID {0} on host {1}",
-                locatorPID, m_locatorHost);
-            }
-            else
-            {
-              if (!KillLocalGFJava(locatorPID, "-15") &&
-                  !KillLocalGFJava(locatorPID, "-9"))
-              {
-                LogSevere("ClientExit() Error while stopping " +
-                  "locator. Please check the logs in {0}", locatorDir);
-              }
-              else
-              {
-                LogInfo("ClientExit() successfully stopped locator on host {0}",
-                  m_locatorHost);
-              }
-            }
-          }
-        }
-        }
-      }
-      locCount = 0;
-      m_locatorHost = null;
-      m_locatorType = null;
-      Util.BBRemove(string.Empty, "LOCATOR_ADDRESS");
-      Util.BBRemove(string.Empty, "LOCATOR_ADDRESS_POOL");
-      m_exiting = false;
-    }
-  }
-}
diff --git a/tests/cli/NewTestObject/CMakeLists.txt b/tests/cli/NewTestObject/CMakeLists.txt
new file mode 100644
index 0000000..4605cb7
--- /dev/null
+++ b/tests/cli/NewTestObject/CMakeLists.txt
@@ -0,0 +1,61 @@
+# 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(NewTestObject CSharp)
+
+add_library(NewTestObject SHARED
+  #ArrayOfByte.cs
+  #BatchObject.cs
+  CMakeLists.txt
+  DeltaEx.cs
+  #DeltaFastAssetAccount.cs
+  #DeltaPSTObject.cs
+  DeltaTestImpl.cs
+  #EqStruct.cs
+  #FastAsset.cs
+  #FastAssetAccount.cs
+  #NoopAuthInit.cs
+  PdxAutoSerializerObj.cs
+  Portfolio.cs
+  PortfolioPdx.cs
+  Position.cs
+  PositionPdx.cs
+  #PSTObject.cs
+  SimpleCacheListener.cs
+  TestObject1.cs
+  #TimeStampdObject.cs
+)
+
+target_link_libraries(NewTestObject
+  PUBLIC
+    Apache.Geode
+    DUnitFramework
+)
+
+set_target_properties(NewTestObject PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode.Client.Tests
+  VS_GLOBAL_TreatWarningsAsErrors True
+  VS_GLOBAL_PROJECT_TYPES "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Data"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(NewTestObject PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
+endif()
diff --git a/tests/cli/NewTestObject/SimpleCacheListener.cs b/tests/cli/NewTestObject/SimpleCacheListener.cs
index 60ebd20..ee7077d 100644
--- a/tests/cli/NewTestObject/SimpleCacheListener.cs
+++ b/tests/cli/NewTestObject/SimpleCacheListener.cs
@@ -24,7 +24,7 @@
   /// <summary>
   /// Capture and display cache events.
   /// </summary>
-  class SimpleCacheListener<TKey, TValue> : ICacheListener<TKey, TValue>
+  public class SimpleCacheListener<TKey, TValue> : ICacheListener<TKey, TValue>
   {
     #region ICacheListener Members
     public static bool isSuccess = true;
diff --git a/tests/cli/PdxVersion1Lib/CMakeLists.txt b/tests/cli/PdxVersion1Lib/CMakeLists.txt
new file mode 100644
index 0000000..0a8c015
--- /dev/null
+++ b/tests/cli/PdxVersion1Lib/CMakeLists.txt
@@ -0,0 +1,42 @@
+# 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(PdxVersion1Lib CSharp)
+
+add_library(PdxVersion1Lib SHARED
+  Properties/AssemblyInfo.cs
+  Version1.cs
+)
+
+target_link_libraries(PdxVersion1Lib
+  PUBLIC
+    Apache.Geode
+)
+
+set_target_properties(PdxVersion1Lib PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE PdxVersionTests
+  VS_GLOBAL_TreatWarningsAsErrors True
+  VS_GLOBAL_PROJECT_TYPES "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Data"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(PdxVersion1Lib PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
+endif()
diff --git a/tests/cli/PdxVersion1Lib/PdxVersion1Lib.csproj.in b/tests/cli/PdxVersion1Lib/PdxVersion1Lib.csproj.in
deleted file mode 100644
index 7f76396..0000000
--- a/tests/cli/PdxVersion1Lib/PdxVersion1Lib.csproj.in
+++ /dev/null
@@ -1,141 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-    <CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-    <CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{D421A19F-9EDC-3838-A9D3-12F5ED663E6E}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>PdxVersion1Lib</RootNamespace>
-    <AssemblyName>PdxVersion1Lib</AssemblyName>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <Optimize>false</Optimize>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>659</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>659</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>659</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>659</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>659</NoWarn>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\clicache\src\Apache.Geode.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>    
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\PdxVersion1Lib\Version1.cs">
-      <Link>Version1.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\PdxVersion1Lib\Properties\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/tests/cli/PdxVersion1Lib/Version1.cs b/tests/cli/PdxVersion1Lib/Version1.cs
index 6c38eb6..1a92ce5 100755
--- a/tests/cli/PdxVersion1Lib/Version1.cs
+++ b/tests/cli/PdxVersion1Lib/Version1.cs
@@ -928,10 +928,11 @@
       return false;
     }
 
-    //public override int GetHashCode()
-    //{
-    //  return _id.GetHashCode();
-    //}
+    public override int GetHashCode()
+    {
+      return base.GetHashCode();
+    }
+
     #region IPdxSerializer Members
 
     public object FromData(string classname, IPdxReader reader)
@@ -1584,6 +1585,13 @@
                 throw new Exception("pdx enum is not equal");
             return true;
         }
+
+
+        public override int GetHashCode()
+        {
+            return base.GetHashCode();
+        }
+
         public void FromData(IPdxReader reader)
         {
             //byte[][] baa = reader.ReadArrayOfByteArrays("m_byteByteArray");
diff --git a/tests/cli/PdxVersion2Lib/CMakeLists.txt b/tests/cli/PdxVersion2Lib/CMakeLists.txt
new file mode 100644
index 0000000..d4b15b2
--- /dev/null
+++ b/tests/cli/PdxVersion2Lib/CMakeLists.txt
@@ -0,0 +1,42 @@
+# 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(PdxVersion2Lib CSharp)
+
+add_library(PdxVersion2Lib SHARED
+  Properties/AssemblyInfo.cs
+  Version2.cs
+)
+
+target_link_libraries(PdxVersion2Lib
+  PUBLIC
+    Apache.Geode
+)
+
+set_target_properties(PdxVersion2Lib PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE PdxVersionTests
+  VS_GLOBAL_TreatWarningsAsErrors True
+  VS_GLOBAL_PROJECT_TYPES "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Data"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(PdxVersion2Lib PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
+endif()
diff --git a/tests/cli/PdxVersion2Lib/PdxVersion2Lib.csproj.in b/tests/cli/PdxVersion2Lib/PdxVersion2Lib.csproj.in
deleted file mode 100644
index 0decded..0000000
--- a/tests/cli/PdxVersion2Lib/PdxVersion2Lib.csproj.in
+++ /dev/null
@@ -1,137 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-    <CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-    <CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{406859C6-CC02-3AE9-9B89-AA99D0BF474A}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>PdxVersion2Lib</RootNamespace>
-    <AssemblyName>PdxVersion2Lib</AssemblyName>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <NoWarn>659</NoWarn>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <PlatformTarget>x86</PlatformTarget>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Xml" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\clicache\src\Apache.Geode.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\PdxVersion2Lib\Version2.cs">
-      <Link>Version2.cs</Link>
-    </Compile>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\PdxVersion2Lib\Properties\AssemblyInfo.cs">
-      <Link>AssemblyInfo.cs</Link>
-    </Compile>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/tests/cli/SecurityUtil/CMakeLists.txt b/tests/cli/SecurityUtil/CMakeLists.txt
new file mode 100644
index 0000000..d3bb9f6
--- /dev/null
+++ b/tests/cli/SecurityUtil/CMakeLists.txt
@@ -0,0 +1,48 @@
+# 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(SecurityUtil CSharp)
+
+add_library(SecurityUtil SHARED
+  AuthzCredentialGeneratorN.cs
+  CredentialGeneratorN.cs
+  DummyAuthorization3N.cs
+  LdapCredentialGeneratorN.cs
+  #PKCSCredentialGeneratorN.cs
+  XmlAuthzCredentialGeneratorN.cs
+)
+
+target_link_libraries(SecurityUtil
+  PUBLIC
+    Apache.Geode
+    DUnitFramework
+    Apache.Geode.Templates.Cache.Security
+)
+
+set_target_properties(SecurityUtil PROPERTIES
+  VS_GLOBAL_ROOTNAMESPACE Apache.Geode.Client.Tests
+  VS_GLOBAL_TreatWarningsAsErrors True
+  VS_GLOBAL_PROJECT_TYPES "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+  VS_DOTNET_REFERENCES "System;System.Xml;System.Data"
+  FOLDER cli/test/integration
+)
+
+if(NOT "${STRONG_NAME_KEY}" STREQUAL "")
+  set_target_properties(SecurityUtil PROPERTIES
+    VS_GLOBAL_SignAssembly "true"
+    VS_GLOBAL_AssemblyOriginatorKeyFile ${STRONG_NAME_KEY}
+  )
+endif()
diff --git a/tests/cli/SecurityUtil/SecurityUtil.csproj.in b/tests/cli/SecurityUtil/SecurityUtil.csproj.in
deleted file mode 100644
index a6ae959..0000000
--- a/tests/cli/SecurityUtil/SecurityUtil.csproj.in
+++ /dev/null
@@ -1,129 +0,0 @@
-<?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.
--->
-<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
-  <PropertyGroup>
-    <CMAKE_SOURCE_DIR>${CMAKE_SOURCE_DIR_NATIVE}</CMAKE_SOURCE_DIR>
-    <CMAKE_CURRENT_SOURCE_DIR>${CMAKE_CURRENT_SOURCE_DIR_NATIVE}</CMAKE_CURRENT_SOURCE_DIR>
-    <CMAKE_BINARY_DIR>${CMAKE_BINARY_DIR_NATIVE}</CMAKE_BINARY_DIR>
-    <CMAKE_CURRENT_BINARY_DIR>${CMAKE_CURRENT_BINARY_DIR_NATIVE}</CMAKE_CURRENT_BINARY_DIR>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x64</Platform>
-    <ProductVersion>8.0.50727</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{79DD6052-5570-30C0-8B0C-4974F50ACF12}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Apache.Geode.Client.Tests</RootNamespace>
-    <AssemblyName>SecurityUtil</AssemblyName>
-    <SignAssembly>${STRONG_NAME_KEY_ENABLED}</SignAssembly>
-    <AssemblyOriginatorKeyFile>${STRONG_NAME_KEY}</AssemblyOriginatorKeyFile>
-    <TargetFrameworkVersion>${DOTNET_TARGET_FRAMEWORK_VERSION}</TargetFrameworkVersion>
-    <FileUpgradeFlags>
-    </FileUpgradeFlags>
-    <OldToolsVersion>2.0</OldToolsVersion>
-    <UpgradeBackupLocation />
-    <PublishUrl>publish\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
-    <DebugSymbols>true</DebugSymbols>
-    <Optimize>false</Optimize>
-    <IntermediateOutputPath>Debug</IntermediateOutputPath>
-    <OutputPath>Debug</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <DebugType>full</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>Release</IntermediateOutputPath>
-    <OutputPath>Release</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'RelWithDebInfo|x64' ">
-    <DefineConstants>TRACE</DefineConstants>
-    <Optimize>true</Optimize>
-    <IntermediateOutputPath>RelWithDebInfo</IntermediateOutputPath>
-    <OutputPath>RelWithDebInfo</OutputPath>
-    <DebugType>pdbonly</DebugType>
-    <PlatformTarget>x64</PlatformTarget>
-    <ErrorReport>prompt</ErrorReport>
-    <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
-    <WarningLevel>4</WarningLevel>
-    <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="System" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="$(CMAKE_BINARY_DIR)\clicache\src\Apache.Geode.vcxproj">
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\..\clicache\templates\Templates.csproj">  
-      <CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
-      <ReferenceOutputAssembly>true</ReferenceOutputAssembly>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\SecurityUtil\AuthzCredentialGeneratorN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\SecurityUtil\CredentialGeneratorN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\SecurityUtil\DummyAuthorization3N.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\SecurityUtil\LdapCredentialGeneratorN.cs" />
-    <Compile Include="$(CMAKE_CURRENT_SOURCE_DIR)\SecurityUtil\XmlAuthzCredentialGeneratorN.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\DUnitFramework\DUnitFramework.csproj">
-      <Project>{796727E8-3A6A-46BE-A2DB-584A4774CD51}</Project>
-      <Name>DUnitFramework</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
-</Project>
diff --git a/tests/cpp/fwklib/CMakeLists.txt b/tests/cpp/fwklib/CMakeLists.txt
index 8aeec6a..783d38d 100644
--- a/tests/cpp/fwklib/CMakeLists.txt
+++ b/tests/cpp/fwklib/CMakeLists.txt
@@ -13,7 +13,6 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-cmake_minimum_required(VERSION 3.10)
 project(framework LANGUAGES CXX)
 
 add_library(framework STATIC
@@ -73,4 +72,4 @@
 add_clangformat(framework)
 
 # For Visual Studio organization
-set_target_properties(framework PROPERTIES FOLDER cpp/test/integration)
+set_target_properties(framework PROPERTIES FOLDER cpp/test/integration/legacy)
