Merge pull request #4188 from Nordix/feature/GEODE-7319

GEODE-7319: Solution for flaky test
diff --git a/boms/geode-all-bom/src/test/resources/expected-pom.xml b/boms/geode-all-bom/src/test/resources/expected-pom.xml
index f5ca0b7..258cde1 100644
--- a/boms/geode-all-bom/src/test/resources/expected-pom.xml
+++ b/boms/geode-all-bom/src/test/resources/expected-pom.xml
@@ -364,13 +364,13 @@
       <dependency>
         <groupId>org.eclipse.jetty</groupId>
         <artifactId>jetty-webapp</artifactId>
-        <version>9.4.12.v20180830</version>
+        <version>9.4.21.v20190926</version>
         <scope>compile</scope>
       </dependency>
       <dependency>
         <groupId>org.eclipse.jetty</groupId>
         <artifactId>jetty-server</artifactId>
-        <version>9.4.12.v20180830</version>
+        <version>9.4.21.v20190926</version>
         <scope>compile</scope>
       </dependency>
       <dependency>
diff --git a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
index 8190f24..04c8a99 100644
--- a/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
+++ b/buildSrc/src/main/groovy/org/apache/geode/gradle/plugins/DependencyConstraints.groovy
@@ -57,7 +57,7 @@
 
     // The jetty version is also hard-coded in geode-assembly:test
     // at o.a.g.sessions.tests.GenericAppServerInstall.java
-    deps.put("jetty.version", "9.4.12.v20180830")
+    deps.put("jetty.version", "9.4.21.v20190926")
 
     // These version numbers are consumed by protobuf configurations that are plugin-specific and not
     // part of the typical Gradle dependency configurations.
diff --git a/ci/pipelines/geode-build/jinja.template.yml b/ci/pipelines/geode-build/jinja.template.yml
index 116099c..3d3f2e9 100644
--- a/ci/pipelines/geode-build/jinja.template.yml
+++ b/ci/pipelines/geode-build/jinja.template.yml
@@ -379,20 +379,26 @@
       run:
         path: bash
         args:
-        - -ecx
+        - -cx
         - |-
           pushd geode
             GEODE_SHA=$(git rev-parse HEAD)
           popd
           GEODE_SEMVER=$(cat geode-build-version/number)
 
-          cat > geode-passing-tokens/passing-build-tokens.json <<JSON
+          GS_PATH=gs://((artifact-bucket))/semvers/((pipeline-prefix))((geode-build-branch))/passing-build-tokens.json
+          CURRENT_PASSING_SHA=$(gsutil cat ${GS_PATH} | jq -r .ref)
+          set -e
+          # Check that the incoming GEODE_SHA is a descendent of the currently stored value.
+          # Keeps us from winding back the repository in the case of an out-of-order pipeline pass
+          if [ -z "${CURRENT_PASSING_SHA}" ] || (cd geode; git merge-base --is-ancestor ${CURRENT_PASSING_SHA} ${GEODE_SHA}); then
+            cat > geode-passing-tokens/passing-build-tokens.json <<JSON
           {
             "ref": "${GEODE_SHA}",
             "semver": "${GEODE_SEMVER}"
           }
           JSON
-          echo "${GEODE_SHA}" > geode-passing-tokens/sha
+          fi
   - aggregate:
     - put: geode-passing-tokens
       params:
diff --git a/ci/scripts/attach_sha_to_branch.sh b/ci/scripts/attach_sha_to_branch.sh
index dc20f96..06223f8 100755
--- a/ci/scripts/attach_sha_to_branch.sh
+++ b/ci/scripts/attach_sha_to_branch.sh
@@ -23,6 +23,6 @@
 
 pushd ${REPO_DIR}
   DESIRED_SHA=$(git rev-parse HEAD)
-  git checkout ${DESIRED_BRANCH}
+  git checkout --force ${DESIRED_BRANCH}
   git reset --hard ${DESIRED_SHA}
 popd
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionCacheJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionCacheJUnitTest.java
new file mode 100644
index 0000000..04cc183
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionCacheJUnitTest.java
@@ -0,0 +1,124 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.juli.logging.Log;
+import org.junit.Test;
+
+import org.apache.geode.cache.CustomExpiry;
+import org.apache.geode.cache.EntryNotFoundException;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.cache.execute.Execution;
+import org.apache.geode.distributed.DistributedSystem;
+import org.apache.geode.modules.util.RegionConfiguration;
+
+public abstract class AbstractSessionCacheJUnitTest {
+
+  protected String sessionRegionName = "sessionRegion";
+  private String sessionRegionAttributesId = RegionShortcut.PARTITION.toString();
+  private int nonDefaultMaxInactiveInterval = RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL + 1;
+  private boolean gatewayDeltaReplicationEnabled = true;
+  private boolean gatewayReplicationEnabled = true;
+  private boolean enableDebugListener = true;
+
+
+  protected SessionManager sessionManager = mock(SessionManager.class);
+  @SuppressWarnings("unchecked")
+  protected Region<String, HttpSession> sessionRegion = mock(Region.class);
+  protected DistributedSystem distributedSystem = mock(DistributedSystem.class);
+  protected Log logger = mock(Log.class);
+  protected Execution emptyExecution = mock(Execution.class);
+
+  protected AbstractSessionCache sessionCache;
+
+  @Test
+  public void createRegionConfigurationSetsAppropriateValuesWithDefaultMaxInactiveInterval() {
+    RegionConfiguration config = spy(new RegionConfiguration());
+    doReturn(config).when(sessionCache).getNewRegionConfiguration();
+
+    when(sessionManager.getRegionName()).thenReturn(sessionRegionName);
+    when(sessionManager.getRegionAttributesId()).thenReturn(sessionRegionAttributesId);
+    when(sessionManager.getMaxInactiveInterval())
+        .thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL);
+    when(sessionManager.getEnableGatewayDeltaReplication())
+        .thenReturn(gatewayDeltaReplicationEnabled);
+    when(sessionManager.getEnableGatewayReplication()).thenReturn(gatewayReplicationEnabled);
+    when(sessionManager.getEnableDebugListener()).thenReturn(enableDebugListener);
+
+    sessionCache.createRegionConfiguration();
+
+    verify(config).setRegionName(sessionRegionName);
+    verify(config).setRegionAttributesId(sessionRegionAttributesId);
+    verify(config, times(0)).setMaxInactiveInterval(anyInt());
+    verify(config, times(0)).setCustomExpiry(any(CustomExpiry.class));
+    verify(config).setEnableGatewayDeltaReplication(gatewayDeltaReplicationEnabled);
+    verify(config).setEnableGatewayReplication(gatewayReplicationEnabled);
+    verify(config).setEnableDebugListener(enableDebugListener);
+  }
+
+  @Test
+  public void createRegionConfigurationSetsAppropriateValuesWithNonDefaultMaxInactiveInterval() {
+    RegionConfiguration config = spy(new RegionConfiguration());
+    doReturn(config).when(sessionCache).getNewRegionConfiguration();
+
+    when(sessionManager.getRegionName()).thenReturn(sessionRegionName);
+    when(sessionManager.getRegionAttributesId()).thenReturn(sessionRegionAttributesId);
+    when(sessionManager.getMaxInactiveInterval()).thenReturn(nonDefaultMaxInactiveInterval);
+    when(sessionManager.getEnableGatewayDeltaReplication())
+        .thenReturn(gatewayDeltaReplicationEnabled);
+    when(sessionManager.getEnableGatewayReplication()).thenReturn(gatewayReplicationEnabled);
+    when(sessionManager.getEnableDebugListener()).thenReturn(enableDebugListener);
+
+    sessionCache.createRegionConfiguration();
+
+    verify(config).setRegionName(sessionRegionName);
+    verify(config).setRegionAttributesId(sessionRegionAttributesId);
+    verify(config).setMaxInactiveInterval(nonDefaultMaxInactiveInterval);
+    verify(config).setCustomExpiry(any(CustomExpiry.class));
+    verify(config).setEnableGatewayDeltaReplication(gatewayDeltaReplicationEnabled);
+    verify(config).setEnableGatewayReplication(gatewayReplicationEnabled);
+    verify(config).setEnableDebugListener(enableDebugListener);
+  }
+
+  @Test
+  public void destroySessionDoesNotThrowExceptionWhenGetOperatingRegionThrowsEntryNotFoundException() {
+    EntryNotFoundException exception = new EntryNotFoundException("Entry not found.");
+    String sessionId = "sessionId";
+    // For Client/Server the operating Region is always the session Region, for peer to peer this is
+    // only true when
+    // local caching is not enabled. For the purposes of this test the behavior is equivalent
+    // regardless of local
+    // caching.
+    when(sessionCache.getOperatingRegion()).thenReturn(sessionRegion);
+    doThrow(exception).when(sessionRegion).destroy(sessionId);
+
+    sessionCache.destroySession(sessionId);
+    verify(sessionCache).getOperatingRegion();
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/ClientServerSessionCacheJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/ClientServerSessionCacheJUnitTest.java
new file mode 100644
index 0000000..2e34681
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/ClientServerSessionCacheJUnitTest.java
@@ -0,0 +1,318 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.servlet.http.HttpSession;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import org.apache.geode.Statistics;
+import org.apache.geode.cache.AttributesMutator;
+import org.apache.geode.cache.CacheListener;
+import org.apache.geode.cache.DataPolicy;
+import org.apache.geode.cache.InterestResultPolicy;
+import org.apache.geode.cache.RegionAttributes;
+import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.cache.client.ClientCache;
+import org.apache.geode.cache.client.ClientRegionFactory;
+import org.apache.geode.cache.client.ClientRegionShortcut;
+import org.apache.geode.cache.client.internal.InternalClientCache;
+import org.apache.geode.cache.client.internal.PoolImpl;
+import org.apache.geode.cache.execute.Function;
+import org.apache.geode.cache.execute.FunctionException;
+import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.modules.session.catalina.callback.SessionExpirationCacheListener;
+import org.apache.geode.modules.util.BootstrappingFunction;
+import org.apache.geode.modules.util.CreateRegionFunction;
+import org.apache.geode.modules.util.DebugCacheListener;
+import org.apache.geode.modules.util.RegionConfiguration;
+import org.apache.geode.modules.util.RegionStatus;
+import org.apache.geode.modules.util.SessionCustomExpiry;
+import org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction;
+import org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction;
+
+public class ClientServerSessionCacheJUnitTest extends AbstractSessionCacheJUnitTest {
+
+  private List<RegionStatus> regionStatusResultList = new ArrayList<>();
+  private ClientCache cache = mock(GemFireCacheImpl.class);
+  private ResultCollector collector = mock(ResultCollector.class);
+  private Statistics stats = mock(Statistics.class);
+  @SuppressWarnings("unchecked")
+  private ClientRegionFactory<String, HttpSession> regionFactory = mock(ClientRegionFactory.class);
+  @SuppressWarnings("unchecked")
+  private RegionAttributes<String, HttpSession> attributes = mock(RegionAttributes.class);
+
+  @Before
+  public void setUp() {
+    sessionCache = spy(new ClientServerSessionCache(sessionManager, cache));
+    doReturn(emptyExecution).when((ClientServerSessionCache) sessionCache)
+        .getExecutionForFunctionOnServers();
+    doReturn(emptyExecution).when((ClientServerSessionCache) sessionCache)
+        .getExecutionForFunctionOnServersWithArguments(any());
+    doReturn(emptyExecution).when((ClientServerSessionCache) sessionCache)
+        .getExecutionForFunctionOnServerWithRegionConfiguration(any());
+    doReturn(emptyExecution).when((ClientServerSessionCache) sessionCache)
+        .getExecutionForFunctionOnRegionWithFilter(any());
+
+    when(sessionManager.getLogger()).thenReturn(logger);
+    when(sessionManager.getEnableLocalCache()).thenReturn(true);
+    when(sessionManager.getRegionName()).thenReturn(sessionRegionName);
+    when(sessionManager.getMaxInactiveInterval())
+        .thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL);
+
+    when(cache.getDistributedSystem()).thenReturn(distributedSystem);
+    doReturn(regionFactory).when(cache)
+        .createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU);
+    when(((InternalClientCache) cache).isClient()).thenReturn(true);
+
+    when(emptyExecution.execute(any(Function.class))).thenReturn(collector);
+    when(emptyExecution.execute(any(String.class))).thenReturn(collector);
+
+    when(collector.getResult()).thenReturn(regionStatusResultList);
+
+    when(distributedSystem.createAtomicStatistics(any(), any())).thenReturn(stats);
+
+    regionStatusResultList.clear();
+    regionStatusResultList.add(RegionStatus.VALID);
+  }
+
+  @Test
+  public void initializeSessionCacheSucceeds() {
+    sessionCache.initialize();
+
+    verify(emptyExecution).execute(any(BootstrappingFunction.class));
+    verify(emptyExecution).execute(CreateRegionFunction.ID);
+    verify(cache).createClientRegionFactory(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU);
+    verify(regionFactory, times(0)).setStatisticsEnabled(true);
+    verify(regionFactory, times(0)).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
+    verify(regionFactory, times(0)).addCacheListener(any(SessionExpirationCacheListener.class));
+    verify(regionFactory).create(sessionRegionName);
+  }
+
+  @Test
+  public void bootstrappingFunctionThrowsException() {
+    FunctionException exception = new FunctionException();
+
+    ResultCollector exceptionCollector = mock(ResultCollector.class);
+
+    when(emptyExecution.execute(new BootstrappingFunction())).thenReturn(exceptionCollector);
+    when(exceptionCollector.getResult()).thenThrow(exception);
+
+    sessionCache.initialize();
+
+    verify(logger).warn("Caught unexpected exception:", exception);
+  }
+
+
+  @Test
+  public void createOrRetrieveRegionThrowsException() {
+    RuntimeException exception = new RuntimeException();
+    doThrow(exception).when((ClientServerSessionCache) sessionCache).createLocalSessionRegion();
+
+    assertThatThrownBy(() -> sessionCache.initialize()).hasCause(exception)
+        .isInstanceOf(IllegalStateException.class);
+
+    verify(logger).fatal("Unable to create or retrieve region", exception);
+
+  }
+
+  @Test
+  public void createRegionFunctionFailsOnServer() {
+    ArgumentCaptor<String> stringCaptor = ArgumentCaptor.forClass(String.class);
+
+    regionStatusResultList.clear();
+    regionStatusResultList.add(RegionStatus.INVALID);
+
+    assertThatThrownBy(() -> sessionCache.initialize()).isInstanceOf(IllegalStateException.class)
+        .hasCauseInstanceOf(IllegalStateException.class).hasMessageContaining(
+            "An exception occurred on the server while attempting to create or validate region named "
+                + sessionRegionName
+                + ". See the server log for additional details.");
+
+    verify(logger).fatal(stringCaptor.capture(), any(Exception.class));
+    assertThat(stringCaptor.getValue()).isEqualTo("Unable to create or retrieve region");
+  }
+
+  @Test
+  public void nonDefaultMaxTimeoutIntervalSetsExpirationDetails() {
+    // Setting the mocked return value of getMaxInactiveInterval to something distinctly not equal
+    // to the default
+    when(sessionManager.getMaxInactiveInterval())
+        .thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL + 1);
+
+    sessionCache.initialize();
+
+    verify(regionFactory).setStatisticsEnabled(true);
+    verify(regionFactory).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
+    verify(regionFactory).addCacheListener(any(SessionExpirationCacheListener.class));
+  }
+
+  @Test
+  public void createLocalSessionRegionWithoutEnableLocalCache() {
+    when(sessionManager.getEnableLocalCache()).thenReturn(false);
+    doReturn(regionFactory).when(cache).createClientRegionFactory(ClientRegionShortcut.PROXY);
+    when(regionFactory.create(sessionRegionName)).thenReturn(sessionRegion);
+
+    sessionCache.initialize();
+
+    verify(regionFactory).addCacheListener(any(SessionExpirationCacheListener.class));
+    verify(sessionRegion).registerInterest("ALL_KEYS", InterestResultPolicy.KEYS);
+  }
+
+  @Test
+  public void createOrRetrieveRegionWithNonNullSessionRegionDoesNotCreateRegion() {
+    @SuppressWarnings("unchecked")
+    CacheListener<String, HttpSession>[] cacheListeners =
+        new CacheListener[] {new SessionExpirationCacheListener()};
+    doReturn(sessionRegion).when(cache).getRegion(sessionRegionName);
+    doReturn(attributes).when(sessionRegion).getAttributes();
+    doReturn(cacheListeners).when(attributes).getCacheListeners();
+
+    sessionCache.initialize();
+
+    verify((ClientServerSessionCache) sessionCache, times(0)).createSessionRegionOnServers();
+    verify((ClientServerSessionCache) sessionCache, times(0)).createLocalSessionRegion();
+  }
+
+  @Test
+  public void createOrRetrieveRegionWithNonNullSessionRegionAndNoSessionExpirationCacheListenerCreatesListener() {
+    @SuppressWarnings("unchecked")
+    CacheListener<String, HttpSession>[] cacheListeners =
+        new CacheListener[] {new DebugCacheListener()};
+    @SuppressWarnings("unchecked")
+    AttributesMutator<String, HttpSession> attributesMutator = mock(AttributesMutator.class);
+    doReturn(sessionRegion).when(cache).getRegion(sessionRegionName);
+    doReturn(attributes).when(sessionRegion).getAttributes();
+    doReturn(cacheListeners).when(attributes).getCacheListeners();
+    doReturn(attributesMutator).when(sessionRegion).getAttributesMutator();
+
+    sessionCache.initialize();
+
+    verify(attributesMutator).addCacheListener(any(SessionExpirationCacheListener.class));
+  }
+
+  @Test
+  public void createOrRetrieveRegionWithNonNullSessionProxyRegionRegistersInterestForAllKeys() {
+    @SuppressWarnings("unchecked")
+    CacheListener<String, HttpSession>[] cacheListeners =
+        new CacheListener[] {new SessionExpirationCacheListener()};
+    doReturn(sessionRegion).when(cache).getRegion(sessionRegionName);
+    doReturn(attributes).when(sessionRegion).getAttributes();
+    doReturn(cacheListeners).when(attributes).getCacheListeners();
+    when(attributes.getDataPolicy()).thenReturn(DataPolicy.EMPTY);
+
+    sessionCache.initialize();
+
+    verify(sessionRegion).registerInterest("ALL_KEYS", InterestResultPolicy.KEYS);
+  }
+
+  @Test
+  public void touchSessionsInvokesPRFunctionForPRAndDoesNotThrowExceptionWhenFunctionDoesNotThrowException() {
+    Set<String> sessionIds = new HashSet<>();
+
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
+
+    sessionCache.touchSessions(sessionIds);
+
+    verify(emptyExecution).execute(TouchPartitionedRegionEntriesFunction.ID);
+  }
+
+  @Test
+  public void touchSessionsInvokesPRFunctionForPRAndThrowsExceptionWhenFunctionThrowsException() {
+    Set<String> sessionIds = new HashSet<>();
+    FunctionException exception = new FunctionException();
+    ResultCollector exceptionCollector = mock(ResultCollector.class);
+
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
+    when(emptyExecution.execute(TouchPartitionedRegionEntriesFunction.ID))
+        .thenReturn(exceptionCollector);
+    when(exceptionCollector.getResult()).thenThrow(exception);
+
+    sessionCache.touchSessions(sessionIds);
+    verify(logger).warn("Caught unexpected exception:", exception);
+  }
+
+  @Test
+  public void touchSessionsInvokesRRFunctionForRRAndDoesNotThrowExceptionWhenFunctionDoesNotThrowException() {
+    // Need to invoke this to set the session region
+    when(regionFactory.create(sessionRegionName)).thenReturn(sessionRegion);
+    sessionCache.initialize();
+
+    Set<String> sessionIds = new HashSet<>();
+
+    when(sessionRegion.getFullPath()).thenReturn("/" + sessionRegionName);
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.REPLICATE.toString());
+
+    sessionCache.touchSessions(sessionIds);
+    verify(emptyExecution).execute(TouchReplicatedRegionEntriesFunction.ID);
+  }
+
+  @Test
+  public void touchSessionsInvokesRRFunctionForRRAndThrowsExceptionWhenFunctionThrowsException() {
+    // Need to invoke this to set the session region
+    when(regionFactory.create(sessionRegionName)).thenReturn(sessionRegion);
+    sessionCache.initialize();
+
+    Set<String> sessionIds = new HashSet<>();
+    FunctionException exception = new FunctionException();
+    ResultCollector exceptionCollector = mock(ResultCollector.class);
+
+    when(sessionRegion.getFullPath()).thenReturn("/" + sessionRegionName);
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.REPLICATE.toString());
+    when(emptyExecution.execute(TouchReplicatedRegionEntriesFunction.ID))
+        .thenReturn(exceptionCollector);
+    when(exceptionCollector.getResult()).thenThrow(exception);
+
+    sessionCache.touchSessions(sessionIds);
+    verify(logger).warn("Caught unexpected exception:", exception);
+  }
+
+  @Test
+  public void isBackingCacheEnabledReturnsTrueWhenCommitValveFailfastDisabled() {
+    assertThat(sessionCache.isBackingCacheAvailable()).isTrue();
+  }
+
+  @Test
+  public void isBackingCacheEnabledReturnsValueWhenCommitValveFailfastEnabled() {
+    boolean backingCacheEnabled = false;
+    PoolImpl pool = mock(PoolImpl.class);
+
+    when(sessionManager.isCommitValveFailfastEnabled()).thenReturn(true);
+    doReturn(pool).when((ClientServerSessionCache) sessionCache).findPoolInPoolManager();
+    when(pool.isPrimaryUpdaterAlive()).thenReturn(backingCacheEnabled);
+
+    assertThat(sessionCache.isBackingCacheAvailable()).isEqualTo(backingCacheEnabled);
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionFacadeJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionFacadeJUnitTest.java
new file mode 100644
index 0000000..81254c7
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionFacadeJUnitTest.java
@@ -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.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+
+public class DeltaSessionFacadeJUnitTest {
+
+  @Test
+  public void DeltaSessionFacadeMakesProperCallsOnSessionWhenInvoked() {
+    DeltaSessionInterface session = spy(new DeltaSession());
+
+    DeltaSessionFacade facade = new DeltaSessionFacade(session);
+
+    doNothing().when(session).commit();
+    doReturn(true).when(session).isValid();
+
+    facade.commit();
+    facade.isValid();
+
+    verify(session).commit();
+    verify(session).isValid();
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionJUnitTest.java
new file mode 100644
index 0000000..1d55ce0
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionJUnitTest.java
@@ -0,0 +1,205 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.catalina.Manager;
+import org.apache.catalina.session.StandardSession;
+import org.apache.juli.logging.Log;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.cache.Region;
+import org.apache.geode.internal.util.BlobHelper;
+import org.apache.geode.modules.session.catalina.internal.DeltaSessionAttributeEvent;
+import org.apache.geode.modules.session.catalina.internal.DeltaSessionStatistics;
+
+public class DeltaSessionJUnitTest {
+
+  private DeltaSessionManager manager = mock(DeltaSessionManager.class);
+  private Region<String, HttpSession> sessionRegion = mock(Region.class);
+  private SessionCache sessionCache = mock(ClientServerSessionCache.class);
+  DeltaSessionStatistics stats = mock(DeltaSessionStatistics.class);
+  private final String sessionRegionName = "sessionRegionName";
+  private final String contextName = "contextName";
+  private Log logger = mock(Log.class);
+
+  @Before
+  public void setup() {
+    when(manager.getRegionName()).thenReturn(sessionRegionName);
+    when(manager.getSessionCache()).thenReturn(sessionCache);
+    when(manager.getLogger()).thenReturn(logger);
+    when(manager.getContextName()).thenReturn(contextName);
+    when(manager.getStatistics()).thenReturn(stats);
+    // For Client/Server behavior and some PeerToPeer use cases the session region and operating
+    // regions
+    // will be the same.
+    when(sessionCache.getOperatingRegion()).thenReturn(sessionRegion);
+    when(logger.isDebugEnabled()).thenReturn(true);
+  }
+
+  @Test
+  public void sessionConstructionThrowsIllegalArgumentExceptionIfProvidedManagerIsNotDeltaSessionManager() {
+    Manager invalidManager = mock(Manager.class);
+
+    assertThatThrownBy(() -> new DeltaSession(invalidManager))
+        .isInstanceOf(IllegalArgumentException.class)
+        .hasMessageContaining("The Manager must be an AbstractManager");
+  }
+
+  @Test
+  public void sessionConstructionDoesNotThrowExceptionWithValidArgument() {
+    DeltaSession session = new DeltaSession(manager);
+
+    verify(logger).debug(anyString());
+  }
+
+  @Test
+  public void getSessionCreatesFacadeWhenFacadeIsNullAndPackageProtectionDisabled() {
+    DeltaSession session = new DeltaSession(manager);
+
+    HttpSession returnedSession = session.getSession();
+
+    assertThat(returnedSession).isNotNull();
+  }
+
+  @Test
+  public void getSessionCreatesFacadeWhenFacadeIsNullAndPackageProtectionEnabled() {
+    DeltaSession session = spy(new DeltaSession(manager));
+    DeltaSessionFacade facade = mock(DeltaSessionFacade.class);
+    doReturn(true).when(session).isPackageProtectionEnabled();
+    doReturn(facade).when(session).getNewFacade(any(DeltaSession.class));
+
+    HttpSession returnedSession = session.getSession();
+
+    assertThat(returnedSession).isEqualTo(facade);
+  }
+
+  @Test
+  public void processExpiredIncrementsStatisticsCountForExpiredSessions() {
+    DeltaSession session = spy(new DeltaSession(manager));
+
+    doNothing().when((StandardSession) session).expire(false);
+    session.processExpired();
+
+    verify(stats).incSessionsExpired();
+  }
+
+  @Test
+  public void applyEventsAppliesEachEventAndPutsSessionIntoRegion() {
+    DeltaSessionAttributeEvent event1 = mock(DeltaSessionAttributeEvent.class);
+    DeltaSessionAttributeEvent event2 = mock(DeltaSessionAttributeEvent.class);
+    List<DeltaSessionAttributeEvent> events = new ArrayList<>();
+    events.add(event1);
+    events.add(event2);
+    Region<String, DeltaSessionInterface> region = mock(Region.class);
+    DeltaSession session = spy(new DeltaSession(manager));
+
+    session.applyAttributeEvents(region, events);
+
+    // confirm that events were all added to the queue
+    verify(session).addEventToEventQueue(event1);
+    verify(session).addEventToEventQueue(event2);
+
+    // confirm that session was put into region
+    verify(region).put(session.getId(), session, true);
+  }
+
+  @Test
+  public void commitThrowsIllegalStateExceptionWhenCalledOnInvalidSession() {
+    DeltaSession session = spy(new DeltaSession(manager));
+    String sessionId = "invalidatedSession";
+    doReturn(sessionId).when(session).getId();
+
+    assertThatThrownBy(() -> session.commit()).isInstanceOf(IllegalStateException.class)
+        .hasMessage("commit: Session " + sessionId + " already invalidated");
+  }
+
+  @Test
+  public void getSizeInBytesReturnsProperValueForMultipleAttributes() {
+    String attrName1 = "attrName1";
+    String attrName2 = "attrName2";
+    List attrList = new ArrayList<String>();
+    attrList.add(attrName1);
+    attrList.add(attrName2);
+
+    Enumeration<String> attrNames = Collections.enumeration(attrList);
+
+    byte[] value1 = {0, 0, 0, 0};
+    byte[] value2 = {0, 0, 0, 0, 0};
+    int totalSize = value1.length + value2.length;
+
+    DeltaSession session = spy(new DeltaSession(manager));
+    doReturn(attrNames).when(session).getAttributeNames();
+    doReturn(value1).when(session).getAttributeWithoutDeserialize(attrName1);
+    doReturn(value2).when(session).getAttributeWithoutDeserialize(attrName2);
+
+    int sessionSize = session.getSizeInBytes();
+
+    assertThat(sessionSize).isEqualTo(totalSize);
+  }
+
+  @Test
+  public void serializeLogsWarningWhenExceptionIsThrownDuringSerialization() throws IOException {
+    Object obj = "unserialized object";
+    String exceptionMessaage = "Serialization failed.";
+    IOException exception = new IOException(exceptionMessaage);
+
+    DeltaSession session = spy(new DeltaSession(manager));
+    doThrow(exception).when(session).serializeViaBlobHelper(obj);
+    session.serialize(obj);
+
+    verify(logger).warn(anyString(), any(IOException.class));
+  }
+
+  @Test
+  public void serializeReturnsSerializedObject() throws IOException {
+    Object obj = "unserialized object";
+    byte[] serializedObj = BlobHelper.serializeToBlob(obj);
+
+    DeltaSession session = spy(new DeltaSession(manager));
+    byte[] result = session.serialize(obj);
+
+    assertThat(result).isEqualTo(serializedObj);
+  }
+
+  // @Test
+  // public void testToData() throws IOException {
+  // DeltaSession session = spy(new DeltaSession(manager));
+  // DataOutput out = mock(DataOutput.class);
+  //
+  // session.toData(out);
+  // }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManagerJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManagerJUnitTest.java
new file mode 100644
index 0000000..fec8571
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManagerJUnitTest.java
@@ -0,0 +1,471 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+import static org.apache.geode.modules.util.RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.withSettings;
+
+import java.beans.PropertyChangeEvent;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.http.HttpSession;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.Loader;
+import org.apache.catalina.Session;
+import org.apache.catalina.session.StandardSession;
+import org.apache.juli.logging.Log;
+import org.junit.Test;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.query.FunctionDomainException;
+import org.apache.geode.cache.query.NameResolutionException;
+import org.apache.geode.cache.query.Query;
+import org.apache.geode.cache.query.QueryInvocationTargetException;
+import org.apache.geode.cache.query.SelectResults;
+import org.apache.geode.cache.query.TypeMismatchException;
+import org.apache.geode.cache.query.internal.InternalQueryService;
+import org.apache.geode.cache.query.internal.LinkedResultSet;
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.modules.session.catalina.internal.DeltaSessionStatistics;
+
+public abstract class DeltaSessionManagerJUnitTest {
+
+  protected DeltaSessionManager manager;
+  protected AbstractSessionCache sessionCache;
+  protected Cache cache;
+  protected Log logger;
+  protected Context context;
+  protected DeltaSessionStatistics managerStats;
+  protected DeltaSessionStatistics cacheStats;
+  protected Region<String, HttpSession> operatingRegion;
+
+  public void initTest() {
+    sessionCache = mock(AbstractSessionCache.class);
+    cache = mock(GemFireCacheImpl.class);
+    logger = mock(Log.class);
+    context = mock(Context.class);
+    managerStats = mock(DeltaSessionStatistics.class);
+    cacheStats = mock(DeltaSessionStatistics.class);
+    operatingRegion = mock(Region.class);
+
+    doReturn(sessionCache).when(manager).getSessionCache();
+    doReturn(logger).when(manager).getLogger();
+    doReturn(context).when(manager).getTheContext();
+    doReturn(managerStats).when(manager).getStatistics();
+    doReturn(cacheStats).when(sessionCache).getStatistics();
+    doReturn(operatingRegion).when(sessionCache).getOperatingRegion();
+  }
+
+  @Test
+  public void getRegionAttributesIdSetsIdFromSessionCacheWhenAttributesIdIsNull() {
+    String regionAttributesId = "attributesIdFromSessionCache";
+
+    doReturn(regionAttributesId).when(sessionCache).getDefaultRegionAttributesId();
+    String attrId = manager.getRegionAttributesId();
+
+    verify(sessionCache).getDefaultRegionAttributesId();
+    assertThat(attrId).isEqualTo(regionAttributesId);
+  }
+
+  @Test
+  public void getEnableLocalCacheSetsIdFromSessionCacheWhenEnableLocalCacheIsNull() {
+    boolean isLocalCacheEnabled = true;
+
+    doReturn(isLocalCacheEnabled).when(sessionCache).getDefaultEnableLocalCache();
+    Boolean localCacheEnabledValue = manager.getEnableLocalCache();
+
+    verify(sessionCache).getDefaultEnableLocalCache();
+    assertThat(localCacheEnabledValue).isEqualTo(isLocalCacheEnabled);
+  }
+
+  @Test
+  public void findSessionsReturnsNullWhenIdIsNull() throws IOException {
+    Session session = manager.findSession(null);
+
+    assertThat(session).isNull();
+  }
+
+  @Test
+  public void findSessionsReturnsNullAndLogsMessageWhenContextNameIsNotValid() throws IOException {
+    String sessionId = "sessionId";
+    String contextName = "contextName";
+    String invalidContextName = "invalidContextName";
+
+    DeltaSession expectedSession = mock(DeltaSession.class);
+    when(sessionCache.getSession(sessionId)).thenReturn(expectedSession);
+    when(expectedSession.getContextName()).thenReturn(invalidContextName);
+    when(context.getName()).thenReturn(contextName);
+
+    Session session = manager.findSession(sessionId);
+
+    verify(logger).info(anyString());
+    assertThat(session).isNull();
+  }
+
+  @Test
+  public void findSessionsReturnsNullWhenIdIsNotFound() throws IOException {
+    String sessionId = "sessionId";
+
+    when(sessionCache.getSession(sessionId)).thenReturn(null);
+
+    Session session = manager.findSession(sessionId);
+
+    assertThat(session).isNull();
+  }
+
+  @Test
+  public void findSessionsReturnsProperSessionByIdWhenIdAndContextNameIsValid() throws IOException {
+    String sessionId = "sessionId";
+    String contextName = "contextName";
+
+    DeltaSession expectedSession = mock(DeltaSession.class);
+    when(sessionCache.getSession(sessionId)).thenReturn(expectedSession);
+    when(expectedSession.getContextName()).thenReturn(contextName);
+    when(context.getName()).thenReturn(contextName);
+
+    Session session = manager.findSession(sessionId);
+
+    assertThat(session).isEqualTo(expectedSession);
+  }
+
+  @Test
+  public void removeProperlyDestroysSessionFromSessionCacheWhenSessionIsNotExpired() {
+    DeltaSession sessionToDestroy = mock(DeltaSession.class);
+    String sessionId = "sessionId";
+
+    when(sessionToDestroy.getId()).thenReturn(sessionId);
+    when(sessionToDestroy.getExpired()).thenReturn(false);
+
+    manager.remove(sessionToDestroy);
+
+    verify(sessionCache).destroySession(sessionId);
+  }
+
+  @Test
+  public void removeDoesNotDestroySessionFromSessionCacheWhenSessionIsExpired() {
+    DeltaSession sessionToDestroy = mock(DeltaSession.class);
+    String sessionId = "sessionId";
+
+    when(sessionToDestroy.getId()).thenReturn(sessionId);
+    when(sessionToDestroy.getExpired()).thenReturn(true);
+
+    manager.remove(sessionToDestroy);
+
+    verify(sessionCache, times(0)).destroySession(sessionId);
+  }
+
+  @Test
+  public void addPutsSessionIntoSessionCacheAndIncrementsStats() {
+    DeltaSession sessionToPut = mock(DeltaSession.class);
+
+    manager.add(sessionToPut);
+
+    verify(sessionCache).putSession(sessionToPut);
+    verify(cacheStats).incSessionsCreated();
+  }
+
+  @Test
+  public void listIdsListsAllPresentIds() {
+    Set<String> ids = new HashSet<>();
+    ids.add("id1");
+    ids.add("id2");
+    ids.add("id3");
+
+    when(sessionCache.keySet()).thenReturn(ids);
+
+    String listOutput = manager.listSessionIds();
+
+    for (String id : ids) {
+      assertThat(listOutput).contains(id);
+    }
+  }
+
+  @Test
+  public void loadActivatesAndAddsSingleSessionWithValidIdAndMoreRecentAccessTime()
+      throws IOException, ClassNotFoundException {
+    String contextPath = "contextPath";
+    String expectedStoreDir = "";
+    DeltaSession newSession = mock(DeltaSession.class);
+    DeltaSession existingSession = mock(DeltaSession.class);
+
+    prepareMocksForLoadTest(contextPath, newSession, existingSession, expectedStoreDir);
+
+    manager.load();
+
+    verify(newSession).activate();
+    verify(manager).add(newSession);
+  }
+
+  @Test
+  public void loadLogsWarningAndDoesNotAddSessionWhenSessionStoreNotFound()
+      throws IOException, ClassNotFoundException {
+    String contextPath = "contextPath";
+    String expectedStoreDir = "";
+    DeltaSession newSession = mock(DeltaSession.class);
+    DeltaSession existingSession = mock(DeltaSession.class);
+
+    prepareMocksForLoadTest(contextPath, newSession, existingSession, expectedStoreDir);
+
+    doReturn(null).when(manager).getFileAtPath(any(), any());
+
+    manager.load();
+
+    verify(logger).debug("No session store file found");
+    verify(manager, times(0)).add(any());
+  }
+
+  @Test
+  public void loadDoesNotAddSessionToManagerWithValidIdAndLessRecentAccessTime()
+      throws IOException, ClassNotFoundException {
+    String contextPath = "contextPath";
+    String expectedStoreDir = "";
+    DeltaSession newSession = mock(DeltaSession.class);
+    DeltaSession existingSession = mock(DeltaSession.class);
+
+    prepareMocksForLoadTest(contextPath, newSession, existingSession, expectedStoreDir);
+
+    when(existingSession.getLastAccessedTime()).thenReturn(2L);
+
+    manager.load();
+
+    verify(newSession, times(0)).activate();
+    verify(manager, times(0)).add(newSession);
+  }
+
+  @Test
+  public void unloadWritesSingleSessionToDiskWhenIdIsValid()
+      throws IOException, NameResolutionException, TypeMismatchException,
+      QueryInvocationTargetException, FunctionDomainException {
+    String sessionId = "sessionId";
+    DeltaSession session = mock(DeltaSession.class);
+    FileOutputStream fos = mock(FileOutputStream.class);
+    BufferedOutputStream bos = mock(BufferedOutputStream.class);
+    ObjectOutputStream oos = mock(ObjectOutputStream.class);
+
+    prepareMocksForUnloadTest(sessionId, fos, bos, oos, session);
+
+    manager.unload();
+
+    verify((StandardSession) session).writeObjectData(oos);
+  }
+
+  @Test
+  public void unloadDoesNotWriteSessionToDiskAndClosesOutputStreamsWhenOutputStreamThrowsIOException()
+      throws IOException, NameResolutionException, TypeMismatchException,
+      QueryInvocationTargetException, FunctionDomainException {
+    String sessionId = "sessionId";
+    DeltaSession session = mock(DeltaSession.class);
+    FileOutputStream fos = mock(FileOutputStream.class);
+    BufferedOutputStream bos = mock(BufferedOutputStream.class);
+    ObjectOutputStream oos = mock(ObjectOutputStream.class);
+
+    prepareMocksForUnloadTest(sessionId, fos, bos, oos, session);
+
+    String exceptionMessage = "Output Stream IOException";
+
+    IOException exception = new IOException(exceptionMessage);
+
+    doThrow(exception).when(manager).getObjectOutputStream(bos);
+
+    assertThatThrownBy(() -> manager.unload()).isInstanceOf(IOException.class)
+        .hasMessage(exceptionMessage);
+
+    verify((StandardSession) session, times(0)).writeObjectData(oos);
+    verify(bos).close();
+    verify(fos).close();
+  }
+
+  @Test
+  public void unloadDoesNotWriteSessionToDiskAndClosesOutputStreamsWhenSessionIsWrongClass()
+      throws IOException, NameResolutionException, TypeMismatchException,
+      QueryInvocationTargetException, FunctionDomainException {
+    String sessionId = "sessionId";
+    DeltaSession session = mock(DeltaSession.class);
+    FileOutputStream fos = mock(FileOutputStream.class);
+    BufferedOutputStream bos = mock(BufferedOutputStream.class);
+    ObjectOutputStream oos = mock(ObjectOutputStream.class);
+
+    prepareMocksForUnloadTest(sessionId, fos, bos, oos, session);
+
+    Session invalidSession =
+        mock(Session.class, withSettings().extraInterfaces(DeltaSessionInterface.class));
+
+    doReturn(invalidSession).when(manager).findSession(sessionId);
+
+    assertThatThrownBy(() -> manager.unload()).isInstanceOf(IOException.class);
+
+    verify((StandardSession) session, times(0)).writeObjectData(oos);
+    verify(oos).close();
+  }
+
+  @Test
+  public void successfulUnloadWithClientServerSessionCachePerformsLocalDestroy()
+      throws IOException, NameResolutionException, TypeMismatchException,
+      QueryInvocationTargetException, FunctionDomainException {
+    String sessionId = "sessionId";
+    DeltaSession session = mock(DeltaSession.class);
+    FileOutputStream fos = mock(FileOutputStream.class);
+    BufferedOutputStream bos = mock(BufferedOutputStream.class);
+    ObjectOutputStream oos = mock(ObjectOutputStream.class);
+
+    prepareMocksForUnloadTest(sessionId, fos, bos, oos, session);
+
+    when(sessionCache.isClientServer()).thenReturn(true);
+    when(session.getId()).thenReturn(sessionId);
+
+    manager.unload();
+
+    verify((StandardSession) session).writeObjectData(oos);
+    verify(operatingRegion).localDestroy(sessionId);
+  }
+
+  @Test
+  public void propertyChangeSetsMaxInactiveIntervalWithCorrectPropertyNameAndValue() {
+    String propertyName = "sessionTimeout";
+    PropertyChangeEvent event = mock(PropertyChangeEvent.class);
+    Context eventContext = mock(Context.class);
+    Integer newValue = 1;
+
+    when(event.getSource()).thenReturn(eventContext);
+    when(event.getPropertyName()).thenReturn(propertyName);
+    when(event.getNewValue()).thenReturn(newValue);
+
+    manager.propertyChange(event);
+
+    verify(manager).setMaxInactiveInterval(newValue * 60);
+  }
+
+  @Test
+  public void propertyChangeDoesNotSetMaxInactiveIntervalWithIncorrectPropertyName() {
+    String propertyName = "wrong name";
+    PropertyChangeEvent event = mock(PropertyChangeEvent.class);
+    Context eventContext = mock(Context.class);
+
+    when(event.getSource()).thenReturn(eventContext);
+    when(event.getPropertyName()).thenReturn(propertyName);
+
+    manager.propertyChange(event);
+
+    verify(manager, times(0)).setMaxInactiveInterval(anyInt());
+  }
+
+  @Test
+  public void propertyChangeDoesNotSetNewMaxInactiveIntervalWithCorrectPropertyNameAndInvalidPropertyValue() {
+    String propertyName = "sessionTimeout";
+    PropertyChangeEvent event = mock(PropertyChangeEvent.class);
+    Context eventContext = mock(Context.class);
+    Integer newValue = -2;
+    Integer oldValue = DEFAULT_MAX_INACTIVE_INTERVAL;
+
+    when(event.getSource()).thenReturn(eventContext);
+    when(event.getPropertyName()).thenReturn(propertyName);
+    when(event.getNewValue()).thenReturn(newValue);
+    when(event.getOldValue()).thenReturn(oldValue);
+
+    manager.propertyChange(event);
+
+    verify(manager).setMaxInactiveInterval(oldValue);
+  }
+
+  public void prepareMocksForUnloadTest(String sessionId, FileOutputStream fos,
+      BufferedOutputStream bos, ObjectOutputStream oos, DeltaSession session)
+      throws NameResolutionException, TypeMismatchException, QueryInvocationTargetException,
+      FunctionDomainException, IOException {
+    String regionName = "regionName";
+    String contextPath = "contextPath";
+    String catalinaBaseSystemProp = "Catalina/Base";
+    String systemFileSeparator = "/";
+    String expectedStoreDir = catalinaBaseSystemProp + systemFileSeparator + "temp";
+
+    InternalQueryService queryService = mock(InternalQueryService.class);
+    Query query = mock(Query.class);
+    File store = mock(File.class);
+    SelectResults results = new LinkedResultSet();
+
+    when(sessionCache.getCache()).thenReturn(cache);
+    when(context.getPath()).thenReturn(contextPath);
+    when(cache.getQueryService()).thenReturn(queryService);
+    when(queryService.newQuery(anyString())).thenReturn(query);
+    when(query.execute()).thenReturn(results);
+    doReturn(catalinaBaseSystemProp).when(manager)
+        .getSystemPropertyValue(DeltaSessionManager.catalinaBaseSystemProperty);
+    doReturn(systemFileSeparator).when(manager)
+        .getSystemPropertyValue(DeltaSessionManager.fileSeparatorSystemProperty);
+    doReturn(store).when(manager).getFileAtPath(expectedStoreDir, contextPath);
+    doReturn(fos).when(manager).getFileOutputStream(store);
+    doReturn(bos).when(manager).getBufferedOutputStream(fos);
+    doReturn(oos).when(manager).getObjectOutputStream(bos);
+    doReturn(regionName).when(manager).getRegionName();
+    doReturn(session).when(manager).findSession(sessionId);
+    doNothing().when(manager).writeToObjectOutputStream(any(), any());
+
+    results.add(sessionId);
+  }
+
+  public void prepareMocksForLoadTest(String contextPath, DeltaSession newSession,
+      DeltaSession existingSession, String expectedStoreDir)
+      throws IOException, ClassNotFoundException {
+    String catalinaBaseSystemProp = "Catalina/Base";
+    String systemFileSeparator = "/";
+    expectedStoreDir = catalinaBaseSystemProp + systemFileSeparator + "temp";
+    String newSessionId = "newSessionId";
+
+    File store = mock(File.class);
+    FileInputStream fis = mock(FileInputStream.class);
+    BufferedInputStream bis = mock(BufferedInputStream.class);
+    ObjectInputStream ois = mock(ObjectInputStream.class);
+    Loader loader = mock(Loader.class);
+
+    when(context.getPath()).thenReturn(contextPath);
+    when(context.getLoader()).thenReturn(loader);
+    when(newSession.getId()).thenReturn(newSessionId);
+    when(newSession.getLastAccessedTime()).thenReturn(1L);
+    when(newSession.isValid()).thenReturn(true);
+    when(existingSession.getLastAccessedTime()).thenReturn(0L);
+    doReturn(catalinaBaseSystemProp).when(manager).getSystemPropertyValue("catalina.base");
+    doReturn(systemFileSeparator).when(manager).getSystemPropertyValue("file.separator");
+    doReturn(store).when(manager).getFileAtPath(expectedStoreDir, contextPath);
+    doReturn(fis).when(manager).getFileInputStream(store);
+    doReturn(bis).when(manager).getBufferedInputStream(fis);
+    doReturn(ois).when(manager).getObjectInputStream(bis);
+    doReturn(1).when(manager).getSessionCountFromObjectInputStream(ois);
+    doReturn(newSession).when(manager).getNewSession();
+    doReturn(existingSession).when(operatingRegion).get(newSessionId);
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/PeerToPeerSessionCacheJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/PeerToPeerSessionCacheJUnitTest.java
new file mode 100644
index 0000000..2bea8de
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/PeerToPeerSessionCacheJUnitTest.java
@@ -0,0 +1,204 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.servlet.http.HttpSession;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionFactory;
+import org.apache.geode.cache.RegionShortcut;
+import org.apache.geode.cache.execute.FunctionException;
+import org.apache.geode.cache.execute.ResultCollector;
+import org.apache.geode.modules.session.catalina.callback.SessionExpirationCacheListener;
+import org.apache.geode.modules.util.RegionConfiguration;
+import org.apache.geode.modules.util.SessionCustomExpiry;
+import org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction;
+import org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction;
+
+public class PeerToPeerSessionCacheJUnitTest extends AbstractSessionCacheJUnitTest {
+
+  private String localRegionName = sessionRegionName + "_local";
+  @SuppressWarnings("unchecked")
+  private RegionFactory<String, HttpSession> regionFactory = mock(RegionFactory.class);
+  @SuppressWarnings("unchecked")
+  private Region<String, HttpSession> localRegion = mock(Region.class);
+  private Cache cache = mock(Cache.class);
+
+  @Before
+  public void setUp() {
+    sessionCache = spy(new PeerToPeerSessionCache(sessionManager, cache));
+    doReturn(sessionRegion).when((PeerToPeerSessionCache) sessionCache)
+        .createRegionUsingHelper(any(RegionConfiguration.class));
+    doReturn(true).when((PeerToPeerSessionCache) sessionCache)
+        .isFunctionRegistered(any(String.class));
+
+    when(sessionManager.getRegionName()).thenReturn(sessionRegionName);
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
+    when(sessionManager.getLogger()).thenReturn(logger);
+    when(sessionManager.getEnableLocalCache()).thenReturn(true);
+    when(sessionManager.getMaxInactiveInterval())
+        .thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL);
+
+    when(sessionRegion.getName()).thenReturn(sessionRegionName);
+
+    doReturn(regionFactory).when(cache).createRegionFactory(RegionShortcut.LOCAL_HEAP_LRU);
+    when(regionFactory.create(localRegionName)).thenReturn(localRegion);
+
+    when(cache.getDistributedSystem()).thenReturn(distributedSystem);
+  }
+
+  @Test
+  public void initializeSessionCacheSucceeds() {
+    sessionCache.initialize();
+
+    verify(cache).createRegionFactory(RegionShortcut.LOCAL_HEAP_LRU);
+    verify(regionFactory).create(localRegionName);
+    verify((PeerToPeerSessionCache) sessionCache)
+        .createRegionUsingHelper(any(RegionConfiguration.class));
+    verify(regionFactory, times(0)).setStatisticsEnabled(true);
+    verify(regionFactory, times(0)).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
+    verify(regionFactory, times(0)).addCacheListener(any(SessionExpirationCacheListener.class));
+  }
+
+  @Test
+  public void functionRegistrationDoesNotThrowException() {
+    doReturn(false).when((PeerToPeerSessionCache) sessionCache)
+        .isFunctionRegistered(any(String.class));
+
+    sessionCache.initialize();
+
+    verify((PeerToPeerSessionCache) sessionCache).registerFunctionWithFunctionService(any(
+        TouchPartitionedRegionEntriesFunction.class));
+    verify((PeerToPeerSessionCache) sessionCache).registerFunctionWithFunctionService(any(
+        TouchReplicatedRegionEntriesFunction.class));
+  }
+
+  @Test
+  public void initializeSessionCacheSucceedsWhenSessionRegionAlreadyExists() {
+    doReturn(sessionRegion).when(cache).getRegion(sessionRegionName);
+    doNothing().when((PeerToPeerSessionCache) sessionCache)
+        .validateRegionUsingRegionhelper(any(RegionConfiguration.class), any(Region.class));
+
+    sessionCache.initialize();
+
+    verify((PeerToPeerSessionCache) sessionCache, times(0))
+        .createRegionUsingHelper(any(RegionConfiguration.class));
+  }
+
+  @Test
+  public void nonDefaultMaxTimeoutIntervalSetsExpirationDetails() {
+    // Setting the mocked return value of getMaxInactiveInterval to something distinctly not equal
+    // to the default
+    when(sessionManager.getMaxInactiveInterval())
+        .thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL + 1);
+
+    sessionCache.initialize();
+
+    verify(regionFactory).setStatisticsEnabled(true);
+    verify(regionFactory).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
+    verify(regionFactory).addCacheListener(any(SessionExpirationCacheListener.class));
+  }
+
+  @Test
+  public void initializeSessionCacheSucceedsWhenLocalRegionAlreadyExists() {
+    doReturn(localRegion).when(cache).getRegion(localRegionName);
+
+    sessionCache.initialize();
+
+    verify(regionFactory, times(0)).create(any(String.class));
+  }
+
+
+  @Test
+  public void operationRegionIsCorrectlySetWhenEnableLocalCachingIsFalse() {
+    when(sessionManager.getEnableLocalCache()).thenReturn(false);
+
+    sessionCache.initialize();
+
+    verify(cache, times(0)).getRegion(localRegionName);
+    assertThat(sessionCache.sessionRegion).isEqualTo(sessionCache.operatingRegion);
+  }
+
+  @Test
+  public void touchSessionsWithPartitionedRegionSucceeds() {
+    Set<String> sessionIds = new HashSet<>();
+    ResultCollector collector = mock(ResultCollector.class);
+
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
+    doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
+        .getExecutionForFunctionOnRegionWithFilter(sessionIds);
+    when(emptyExecution.execute(TouchPartitionedRegionEntriesFunction.ID)).thenReturn(collector);
+
+    sessionCache.touchSessions(sessionIds);
+
+    verify(emptyExecution).execute(TouchPartitionedRegionEntriesFunction.ID);
+    verify(collector).getResult();
+  }
+
+  @Test
+  public void touchSessionsWithReplicatedRegionSucceeds() {
+    // Need to invoke this to set the session region
+    sessionCache.initialize();
+
+    Set<String> sessionIds = new HashSet<>();
+    ResultCollector collector = mock(ResultCollector.class);
+
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.REPLICATE.toString());
+    doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
+        .getExecutionForFunctionOnMembersWithArguments(any(Object[].class));
+    when(emptyExecution.execute(TouchReplicatedRegionEntriesFunction.ID)).thenReturn(collector);
+
+    sessionCache.touchSessions(sessionIds);
+
+    verify(emptyExecution).execute(TouchReplicatedRegionEntriesFunction.ID);
+    verify(collector).getResult();
+  }
+
+  @Test
+  public void touchSessionsCatchesThrownException() {
+    Set<String> sessionIds = new HashSet<>();
+    ResultCollector collector = mock(ResultCollector.class);
+    FunctionException exception = new FunctionException();
+
+    when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
+    doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
+        .getExecutionForFunctionOnRegionWithFilter(sessionIds);
+    when(emptyExecution.execute(TouchPartitionedRegionEntriesFunction.ID)).thenReturn(collector);
+    doThrow(exception).when(collector).getResult();
+
+    sessionCache.touchSessions(sessionIds);
+
+    verify(logger).warn("Caught unexpected exception:", exception);
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/callback/SessionExpirationCacheListenerJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/callback/SessionExpirationCacheListenerJUnitTest.java
new file mode 100644
index 0000000..7228fe8
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/callback/SessionExpirationCacheListenerJUnitTest.java
@@ -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.
+ */
+
+package org.apache.geode.modules.session.catalina.callback;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpSession;
+
+import org.junit.Test;
+
+import org.apache.geode.cache.EntryEvent;
+import org.apache.geode.cache.Operation;
+import org.apache.geode.modules.session.catalina.DeltaSession;
+
+public class SessionExpirationCacheListenerJUnitTest {
+  @Test
+  public void TestAfterDestroyProcessesSessionExpiredByGemfire() {
+    SessionExpirationCacheListener listener = new SessionExpirationCacheListener();
+    EntryEvent<String, HttpSession> event = mock(EntryEvent.class);
+    DeltaSession session = mock(DeltaSession.class);
+
+    when(event.getOperation()).thenReturn(Operation.EXPIRE_DESTROY);
+    when(event.getOldValue()).thenReturn(session);
+
+    listener.afterDestroy(event);
+
+    verify(session).processExpired();
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionAttributeEventBatchJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionAttributeEventBatchJUnitTest.java
new file mode 100644
index 0000000..bee73b8
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionAttributeEventBatchJUnitTest.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina.internal;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import org.apache.geode.LogWriter;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.modules.session.catalina.DeltaSessionInterface;
+
+public class DeltaSessionAttributeEventBatchJUnitTest {
+  String regionName = "regionName";
+  String sessionId = "sessionId";
+  LogWriter logWriter = mock(LogWriter.class);
+
+  @Test
+  public void TestApplyForBatch() {
+
+    List<DeltaSessionAttributeEvent> eventList = new ArrayList<>();
+    DeltaSessionAttributeEvent event1 = mock(DeltaSessionAttributeEvent.class);
+    DeltaSessionAttributeEvent event2 = mock(DeltaSessionAttributeEvent.class);
+    eventList.add(event1);
+    eventList.add(event2);
+
+
+    Cache cache = mock(Cache.class);
+    Region<String, DeltaSessionInterface> region = mock(Region.class);
+    DeltaSessionInterface deltaSessionInterface = mock(DeltaSessionInterface.class);
+
+    doReturn(region).when(cache).getRegion(regionName);
+    when(cache.getLogger()).thenReturn(logWriter);
+    when(logWriter.fineEnabled()).thenReturn(false);
+    when(region.get(sessionId)).thenReturn(deltaSessionInterface);
+
+    DeltaSessionAttributeEventBatch batch =
+        new DeltaSessionAttributeEventBatch(regionName, sessionId, eventList);
+
+    batch.apply(cache);
+
+    verify(deltaSessionInterface).applyAttributeEvents(region, eventList);
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionDestroyAttributeEventJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionDestroyAttributeEventJUnitTest.java
new file mode 100644
index 0000000..5ea2648
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionDestroyAttributeEventJUnitTest.java
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina.internal;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+
+import org.apache.geode.modules.session.catalina.DeltaSessionInterface;
+
+public class DeltaSessionDestroyAttributeEventJUnitTest {
+  @Test
+  public void DeltaSessionDestroyAttributeEventAppliesAttributeToSession() {
+    String attributeName = "DestroyAttribute";
+
+    DeltaSessionDestroyAttributeEvent event = new DeltaSessionDestroyAttributeEvent(attributeName);
+    DeltaSessionInterface deltaSessionInterface = mock(DeltaSessionInterface.class);
+    event.apply((deltaSessionInterface));
+
+    verify(deltaSessionInterface).localDestroyAttribute(attributeName);
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionStatisticsJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionStatisticsJUnitTest.java
new file mode 100644
index 0000000..51b8129
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionStatisticsJUnitTest.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina.internal;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+
+import org.apache.geode.Statistics;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+
+public class DeltaSessionStatisticsJUnitTest {
+
+  @Test
+  public void CreatedDeltaSessionStatisticsAccessProperStats() {
+    String appName = "DeltaSessionStatisticsTest";
+
+    InternalDistributedSystem internalDistributedSystem = mock(InternalDistributedSystem.class);
+    Statistics statistics = mock(Statistics.class);
+
+    when(internalDistributedSystem.createAtomicStatistics(any(), any())).thenReturn(statistics);
+
+    DeltaSessionStatistics deltaSessionStatistics =
+        new DeltaSessionStatistics(internalDistributedSystem, appName);
+
+    deltaSessionStatistics.incSessionsCreated();
+    deltaSessionStatistics.incSessionsExpired();
+    deltaSessionStatistics.incSessionsInvalidated();
+
+    deltaSessionStatistics.getSessionsCreated();
+    deltaSessionStatistics.getSessionsExpired();
+    deltaSessionStatistics.getSessionsInvalidated();
+
+    verify(statistics, times(3)).incLong(anyInt(), anyLong());
+    verify(statistics, times(3)).getLong(anyInt());
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionUpdateAttributeEventJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionUpdateAttributeEventJUnitTest.java
new file mode 100644
index 0000000..d356afd
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/session/catalina/internal/DeltaSessionUpdateAttributeEventJUnitTest.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina.internal;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import org.junit.Test;
+
+import org.apache.geode.modules.session.catalina.DeltaSessionInterface;
+
+public class DeltaSessionUpdateAttributeEventJUnitTest {
+  @Test
+  public void DeltaSessionDestroyAttributeEventAppliesAttributeToSession() {
+    String attributeName = "UpdateAttribute";
+    String attributeValue = "UpdateValue";
+
+    DeltaSessionUpdateAttributeEvent event =
+        new DeltaSessionUpdateAttributeEvent(attributeName, attributeValue);
+    DeltaSessionInterface deltaSessionInterface = mock(DeltaSessionInterface.class);
+    event.apply((deltaSessionInterface));
+
+    verify(deltaSessionInterface).localUpdateAttribute(attributeName, attributeValue);
+  }
+}
diff --git a/extensions/geode-modules/src/test/java/org/apache/geode/modules/util/CreateRegionFunctionJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/CreateRegionFunctionJUnitTest.java
similarity index 100%
rename from extensions/geode-modules/src/test/java/org/apache/geode/modules/util/CreateRegionFunctionJUnitTest.java
rename to extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/CreateRegionFunctionJUnitTest.java
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/TouchPartitionedRegionEntriesFunctionJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/TouchPartitionedRegionEntriesFunctionJUnitTest.java
new file mode 100644
index 0000000..6852681
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/TouchPartitionedRegionEntriesFunctionJUnitTest.java
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.util;
+
+
+import static org.assertj.core.internal.bytebuddy.matcher.ElementMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.LogWriter;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.RegionFunctionContext;
+import org.apache.geode.cache.execute.ResultSender;
+
+public class TouchPartitionedRegionEntriesFunctionJUnitTest {
+
+  private TouchPartitionedRegionEntriesFunction function =
+      spy(new TouchPartitionedRegionEntriesFunction());
+  private FunctionContext context = mock(RegionFunctionContext.class);
+  private Cache cache = mock(Cache.class);
+  private LogWriter logger = mock(LogWriter.class);
+  private Region primaryDataSet = mock(Region.class);
+  private ResultSender resultSender = mock(ResultSender.class);
+
+  @Before
+  public void setUp() {
+    when(context.getCache()).thenReturn(cache);
+    when(context.getResultSender()).thenReturn(resultSender);
+    when(cache.getLogger()).thenReturn(logger);
+    when(logger.fineEnabled()).thenReturn(false);
+    doReturn(primaryDataSet).when(function)
+        .getLocalDataForContextViaRegionHelper((RegionFunctionContext) context);
+  }
+
+  @Test
+  public void executeDoesNotThrowExceptionWithProperlyDefinedContext() {
+    doReturn(new HashSet() {}).when((RegionFunctionContext) context).getFilter();
+
+    function.execute(context);
+
+    verify(primaryDataSet, times(0)).get(any());
+    verify(resultSender).lastResult(true);
+  }
+
+  @Test
+  public void executeDoesNotThrowExceptionWithProperlyDefinedContextAndMultipleKeys() {
+    HashSet<String> keys = new HashSet();
+    keys.add("Key1");
+    keys.add("Key2");
+
+    doReturn(keys).when((RegionFunctionContext) context).getFilter();
+
+    function.execute(context);
+
+    verify(primaryDataSet, times(keys.size())).get(anyString());
+    verify(resultSender).lastResult(true);
+  }
+}
diff --git a/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/TouchReplicatedRegionEntriesFunctionJUnitTest.java b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/TouchReplicatedRegionEntriesFunctionJUnitTest.java
new file mode 100644
index 0000000..294317a
--- /dev/null
+++ b/extensions/geode-modules-test/src/main/java/org/apache/geode/modules/util/TouchReplicatedRegionEntriesFunctionJUnitTest.java
@@ -0,0 +1,76 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.util;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.HashSet;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.LogWriter;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.RegionFunctionContext;
+import org.apache.geode.cache.execute.ResultSender;
+
+public class TouchReplicatedRegionEntriesFunctionJUnitTest {
+  private TouchReplicatedRegionEntriesFunction function =
+      spy(new TouchReplicatedRegionEntriesFunction());
+  private FunctionContext context = mock(RegionFunctionContext.class);
+  private Cache cache = mock(Cache.class);
+  private LogWriter logger = mock(LogWriter.class);
+  private Region region = mock(Region.class);
+  private ResultSender resultSender = mock(ResultSender.class);
+  private String regionName = "regionName";
+  private HashSet<String> keys = new HashSet<>();
+  private Object[] arguments = new Object[] {regionName, keys};
+
+  @Before
+  public void setUp() {
+    when(context.getArguments()).thenReturn(arguments);
+    when(context.getCache()).thenReturn(cache);
+    when(context.getResultSender()).thenReturn(resultSender);
+    when(cache.getLogger()).thenReturn(logger);
+    when(logger.fineEnabled()).thenReturn(false);
+  }
+
+  @Test
+  public void executeDoesNotThrowExceptionWithProperlyDefinedContext() {
+    when(cache.getRegion(regionName)).thenReturn(region);
+
+    function.execute(context);
+
+    verify(region).getAll(keys);
+    verify(resultSender).lastResult(true);
+  }
+
+  @Test
+  public void executeDoesNotThrowExceptionWithProperlyDefinedContextAndNullRegion() {
+    when(cache.getRegion(regionName)).thenReturn(null);
+
+    function.execute(context);
+
+    verify(region, times(0)).getAll(keys);
+    verify(resultSender).lastResult(true);
+  }
+}
diff --git a/extensions/geode-modules-tomcat7/build.gradle b/extensions/geode-modules-tomcat7/build.gradle
index f5ff7e9..4c390ba 100644
--- a/extensions/geode-modules-tomcat7/build.gradle
+++ b/extensions/geode-modules-tomcat7/build.gradle
@@ -34,6 +34,10 @@
     // Remove everything related to Tomcat 6.x
     exclude group: 'org.apache.tomcat'
   }
+  testCompile(project(':extensions:geode-modules')) {
+    // Remove everything related to Tomcat 6.x
+    exclude group: 'org.apache.tomcat'
+  }
 
   compile('org.apache.tomcat:tomcat-catalina:' + DependencyConstraints.get('tomcat7.version')) {
     exclude module: 'tomcat-annotations-api'
@@ -44,6 +48,12 @@
   }
   compile('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat7.version'))
 
+
+  testCompile('org.httpunit:httpunit')
+  testCompile('junit:junit')
+  testCompile('org.assertj:assertj-core')
+  testCompile('org.mockito:mockito-core')
+  testCompile(project(':extensions:geode-modules-test'))
   integrationTestCompile(project(':geode-dunit')) {
     exclude module: 'geode-core'
   }
diff --git a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java
index 7bbe80f..e965cc5 100644
--- a/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java
+++ b/extensions/geode-modules-tomcat7/src/main/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManager.java
@@ -39,7 +39,7 @@
    */
   @Override
   public void startInternal() throws LifecycleException {
-    super.startInternal();
+    startInternalBase();
     if (getLogger().isDebugEnabled()) {
       getLogger().debug(this + ": Starting");
     }
@@ -69,7 +69,15 @@
     scheduleTimerTasks();
 
     this.started.set(true);
-    this.setState(LifecycleState.STARTING);
+    this.setLifecycleState(LifecycleState.STARTING);
+  }
+
+  void setLifecycleState(LifecycleState newState) throws LifecycleException {
+    this.setState(newState);
+  }
+
+  void startInternalBase() throws LifecycleException {
+    super.startInternal();
   }
 
   /**
@@ -80,7 +88,7 @@
    */
   @Override
   public void stopInternal() throws LifecycleException {
-    super.stopInternal();
+    stopInternalBase();
     if (getLogger().isDebugEnabled()) {
       getLogger().debug(this + ": Stopping");
     }
@@ -112,7 +120,15 @@
       unregisterCommitSessionValve();
     }
 
-    this.setState(LifecycleState.STOPPING);
+    setLifecycleState(LifecycleState.STOPPING);
+  }
+
+  void stopInternalBase() throws LifecycleException {
+    super.stopInternal();
+  }
+
+  void destroyInternalBase() throws LifecycleException {
+    super.destroyInternal();
   }
 
   /**
diff --git a/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManagerJUnitTest.java b/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManagerJUnitTest.java
new file mode 100644
index 0000000..f1bee51
--- /dev/null
+++ b/extensions/geode-modules-tomcat7/src/test/java/org/apache/geode/modules/session/catalina/Tomcat7DeltaSessionManagerJUnitTest.java
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+
+import org.apache.catalina.Context;
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleState;
+import org.apache.catalina.Pipeline;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+
+public class Tomcat7DeltaSessionManagerJUnitTest extends DeltaSessionManagerJUnitTest {
+  private Pipeline pipeline;
+
+  @Before
+  public void setup() {
+    manager = spy(new Tomcat7DeltaSessionManager());
+    initTest();
+    pipeline = mock(Pipeline.class);
+  }
+
+  @Test
+  public void startInternalSucceedsInitialRun()
+      throws LifecycleException, IOException, ClassNotFoundException {
+    doNothing().when((Tomcat7DeltaSessionManager) manager).startInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+    doReturn(cache).when(manager).getAnyCacheInstance();
+    doReturn(true).when((GemFireCacheImpl) cache).isClient();
+    doNothing().when(manager).initSessionCache();
+    doReturn(pipeline).when(manager).getPipeline();
+
+    // Unit testing for load is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).load();
+
+    doNothing().when((Tomcat7DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STARTING);
+
+    assertThat(manager.started).isFalse();
+    ((Tomcat7DeltaSessionManager) manager).startInternal();
+    assertThat(manager.started).isTrue();
+    verify((Tomcat7DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+  }
+
+  @Test
+  public void startInternalDoesNotReinitializeManagerOnSubsequentCalls()
+      throws LifecycleException, IOException, ClassNotFoundException {
+    doNothing().when((Tomcat7DeltaSessionManager) manager).startInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+    doReturn(cache).when(manager).getAnyCacheInstance();
+    doReturn(true).when((GemFireCacheImpl) cache).isClient();
+    doNothing().when(manager).initSessionCache();
+    doReturn(pipeline).when(manager).getPipeline();
+
+    // Unit testing for load is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).load();
+
+    doNothing().when((Tomcat7DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STARTING);
+
+    assertThat(manager.started).isFalse();
+    ((Tomcat7DeltaSessionManager) manager).startInternal();
+
+    // Verify that various initialization actions were performed
+    assertThat(manager.started).isTrue();
+    verify(manager).initializeSessionCache();
+    verify((Tomcat7DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+
+    // Rerun startInternal
+    ((Tomcat7DeltaSessionManager) manager).startInternal();
+
+    // Verify that the initialization actions were still only performed one time
+    verify(manager).initializeSessionCache();
+    verify((Tomcat7DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+  }
+
+  @Test
+  public void stopInternal() throws LifecycleException, IOException {
+    doNothing().when((Tomcat7DeltaSessionManager) manager).startInternalBase();
+    doNothing().when((Tomcat7DeltaSessionManager) manager).destroyInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+
+    // Unit testing for unload is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).unload();
+
+    doNothing().when((Tomcat7DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STOPPING);
+
+    ((Tomcat7DeltaSessionManager) manager).stopInternal();
+
+    assertThat(manager.started).isFalse();
+    verify((Tomcat7DeltaSessionManager) manager).setLifecycleState(LifecycleState.STOPPING);
+  }
+
+  @Test
+  public void setContainerSetsProperContainerAndMaxInactiveInterval() {
+    Context container = mock(Context.class);
+    int containerMaxInactiveInterval = 3;
+
+    doReturn(containerMaxInactiveInterval).when(container).getSessionTimeout();
+
+    manager.setContainer(container);
+    verify(manager).setMaxInactiveInterval(containerMaxInactiveInterval * 60);
+  }
+}
diff --git a/extensions/geode-modules-tomcat8/build.gradle b/extensions/geode-modules-tomcat8/build.gradle
index f8c7730..721d08d 100644
--- a/extensions/geode-modules-tomcat8/build.gradle
+++ b/extensions/geode-modules-tomcat8/build.gradle
@@ -28,12 +28,23 @@
   distributedTestCompile('junit:junit')
   compile('mx4j:mx4j')
   distributedTestImplementation(project(':geode-logging'))
+  testCompile('org.httpunit:httpunit')
+  testCompile('org.apache.tomcat:tomcat-jaspic-api:' + DependencyConstraints.get('tomcat8.version'))
+  testCompile('org.httpunit:httpunit')
+  testCompile('junit:junit')
+  testCompile('org.assertj:assertj-core')
+  testCompile('org.mockito:mockito-core')
+  testCompile(project(':extensions:geode-modules-test'))
   distributedTestCompile('org.httpunit:httpunit')
   distributedTestCompile('org.apache.tomcat:tomcat-jaspic-api:' + DependencyConstraints.get('tomcat8.version'))
   compile(project(':geode-core'))
   compile(project(':extensions:geode-modules')) {
     exclude group: 'org.apache.tomcat'
   }
+  testCompile(project(':extensions:geode-modules')) {
+    exclude group: 'org.apache.tomcat'
+  }
+
 
   compile('org.apache.tomcat:tomcat-catalina:' + DependencyConstraints.get('tomcat8.version')) {
     exclude module: 'tomcat-annotations-api'
@@ -44,6 +55,16 @@
   }
   compile('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat8.version'))
   compile('javax.servlet:javax.servlet-api')
+  
+  integrationTestCompile(project(':geode-dunit')) {
+    exclude module: 'geode-core'
+  }
+  integrationTestCompile(project(':geode-junit')) {
+    exclude module: 'geode-core'
+  }
+  integrationTestCompile(project(':extensions:geode-modules-test'))
+  integrationTestRuntime('xerces:xercesImpl')
+  integrationTestRuntime('javax.annotation:javax.annotation-api')
 
   distributedTestCompile(project(':geode-dunit')) {
     exclude module: 'geode-core'
diff --git a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java
index 8752b61..8a32ac0 100644
--- a/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java
+++ b/extensions/geode-modules-tomcat8/src/main/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManager.java
@@ -34,7 +34,7 @@
    */
   @Override
   public void startInternal() throws LifecycleException {
-    super.startInternal();
+    startInternalBase();
     if (getLogger().isDebugEnabled()) {
       getLogger().debug(this + ": Starting");
     }
@@ -64,7 +64,15 @@
     scheduleTimerTasks();
 
     this.started.set(true);
-    this.setState(LifecycleState.STARTING);
+    setLifecycleState(LifecycleState.STARTING);
+  }
+
+  void setLifecycleState(LifecycleState newState) throws LifecycleException {
+    this.setState(newState);
+  }
+
+  void startInternalBase() throws LifecycleException {
+    super.startInternal();
   }
 
   /**
@@ -75,7 +83,7 @@
    */
   @Override
   public void stopInternal() throws LifecycleException {
-    super.stopInternal();
+    stopInternalBase();
     if (getLogger().isDebugEnabled()) {
       getLogger().debug(this + ": Stopping");
     }
@@ -92,7 +100,7 @@
     // StandardManager expires all Sessions here.
     // All Sessions are not known by this Manager.
 
-    super.destroyInternal();
+    destroyInternalBase();
 
     // Clear any sessions to be touched
     getSessionsToTouch().clear();
@@ -107,10 +115,18 @@
       unregisterCommitSessionValve();
     }
 
-    this.setState(LifecycleState.STOPPING);
+    setLifecycleState(LifecycleState.STOPPING);
 
   }
 
+  void stopInternalBase() throws LifecycleException {
+    super.stopInternal();
+  }
+
+  void destroyInternalBase() throws LifecycleException {
+    super.destroyInternal();
+  }
+
   @Override
   public int getMaxInactiveInterval() {
     return getContext().getSessionTimeout();
diff --git a/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManagerJUnitTest.java b/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManagerJUnitTest.java
new file mode 100644
index 0000000..1bf7939
--- /dev/null
+++ b/extensions/geode-modules-tomcat8/src/test/java/org/apache/geode/modules/session/catalina/Tomcat8DeltaSessionManagerJUnitTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleState;
+import org.apache.catalina.Pipeline;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+
+public class Tomcat8DeltaSessionManagerJUnitTest extends DeltaSessionManagerJUnitTest {
+  private Pipeline pipeline;
+
+  @Before
+  public void setup() {
+    manager = spy(new Tomcat8DeltaSessionManager());
+    initTest();
+    pipeline = mock(Pipeline.class);
+    doReturn(context).when(manager).getContext();
+  }
+
+  @Test
+  public void startInternalSucceedsInitialRun()
+      throws LifecycleException, IOException, ClassNotFoundException {
+    doNothing().when((Tomcat8DeltaSessionManager) manager).startInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+    doReturn(cache).when(manager).getAnyCacheInstance();
+    doReturn(true).when((GemFireCacheImpl) cache).isClient();
+    doNothing().when(manager).initSessionCache();
+    doReturn(pipeline).when(manager).getPipeline();
+
+    // Unit testing for load is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).load();
+
+    doNothing().when((Tomcat8DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STARTING);
+
+    assertThat(manager.started).isFalse();
+    ((Tomcat8DeltaSessionManager) manager).startInternal();
+    assertThat(manager.started).isTrue();
+    verify((Tomcat8DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+  }
+
+  @Test
+  public void startInternalDoesNotReinitializeManagerOnSubsequentCalls()
+      throws LifecycleException, IOException, ClassNotFoundException {
+    doNothing().when((Tomcat8DeltaSessionManager) manager).startInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+    doReturn(cache).when(manager).getAnyCacheInstance();
+    doReturn(true).when((GemFireCacheImpl) cache).isClient();
+    doNothing().when(manager).initSessionCache();
+    doReturn(pipeline).when(manager).getPipeline();
+
+    // Unit testing for load is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).load();
+
+    doNothing().when((Tomcat8DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STARTING);
+
+    assertThat(manager.started).isFalse();
+    ((Tomcat8DeltaSessionManager) manager).startInternal();
+
+    // Verify that various initialization actions were performed
+    assertThat(manager.started).isTrue();
+    verify(manager).initializeSessionCache();
+    verify((Tomcat8DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+
+    // Rerun startInternal
+    ((Tomcat8DeltaSessionManager) manager).startInternal();
+
+    // Verify that the initialization actions were still only performed one time
+    verify(manager).initializeSessionCache();
+    verify((Tomcat8DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+  }
+
+  @Test
+  public void stopInternal() throws LifecycleException, IOException {
+    doNothing().when((Tomcat8DeltaSessionManager) manager).startInternalBase();
+    doNothing().when((Tomcat8DeltaSessionManager) manager).destroyInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+
+    // Unit testing for unload is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).unload();
+
+    doNothing().when((Tomcat8DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STOPPING);
+
+    ((Tomcat8DeltaSessionManager) manager).stopInternal();
+
+    assertThat(manager.started).isFalse();
+    verify((Tomcat8DeltaSessionManager) manager).setLifecycleState(LifecycleState.STOPPING);
+  }
+
+}
diff --git a/extensions/geode-modules-tomcat9/build.gradle b/extensions/geode-modules-tomcat9/build.gradle
index 280e530..417714a 100644
--- a/extensions/geode-modules-tomcat9/build.gradle
+++ b/extensions/geode-modules-tomcat9/build.gradle
@@ -28,6 +28,9 @@
   compile(project(':extensions:geode-modules')) {
     exclude group: 'org.apache.tomcat'
   }
+  testCompile(project(':extensions:geode-modules')) {
+    exclude group: 'org.apache.tomcat'
+  }
 
   compile('org.apache.tomcat:tomcat-catalina:' + DependencyConstraints.get('tomcat9.version')) {
     exclude module: 'tomcat-annotations-api'
@@ -39,6 +42,12 @@
   compile('org.apache.tomcat:tomcat-juli:' + DependencyConstraints.get('tomcat9.version'))
   compile('javax.servlet:javax.servlet-api:' + '3.1.0')
 
+  testCompile('org.httpunit:httpunit')
+  testCompile('junit:junit')
+  testCompile('org.assertj:assertj-core')
+  testCompile('org.mockito:mockito-core')
+  testCompile(project(':extensions:geode-modules-test')) 
+
   distributedTestCompile(project(':extensions:geode-modules-test'))
 
   distributedTestRuntime('xerces:xercesImpl')
diff --git a/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java
index 973bb3e..ac9ac2c 100644
--- a/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java
+++ b/extensions/geode-modules-tomcat9/src/main/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManager.java
@@ -34,7 +34,7 @@
    */
   @Override
   public void startInternal() throws LifecycleException {
-    super.startInternal();
+    startInternalBase();
     if (getLogger().isDebugEnabled()) {
       getLogger().debug(this + ": Starting");
     }
@@ -64,7 +64,15 @@
     scheduleTimerTasks();
 
     this.started.set(true);
-    this.setState(LifecycleState.STARTING);
+    setLifecycleState(LifecycleState.STARTING);
+  }
+
+  void setLifecycleState(LifecycleState newState) throws LifecycleException {
+    this.setState(newState);
+  }
+
+  void startInternalBase() throws LifecycleException {
+    super.startInternal();
   }
 
   /**
@@ -75,7 +83,7 @@
    */
   @Override
   public void stopInternal() throws LifecycleException {
-    super.stopInternal();
+    stopInternalBase();
     if (getLogger().isDebugEnabled()) {
       getLogger().debug(this + ": Stopping");
     }
@@ -92,7 +100,7 @@
     // StandardManager expires all Sessions here.
     // All Sessions are not known by this Manager.
 
-    super.destroyInternal();
+    destroyInternalBase();
 
     // Clear any sessions to be touched
     getSessionsToTouch().clear();
@@ -107,10 +115,18 @@
       unregisterCommitSessionValve();
     }
 
-    this.setState(LifecycleState.STOPPING);
+    setLifecycleState(LifecycleState.STOPPING);
 
   }
 
+  void stopInternalBase() throws LifecycleException {
+    super.stopInternal();
+  }
+
+  void destroyInternalBase() throws LifecycleException {
+    super.destroyInternal();
+  }
+
   @Override
   public int getMaxInactiveInterval() {
     return getContext().getSessionTimeout();
diff --git a/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManagerJUnitTest.java b/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManagerJUnitTest.java
new file mode 100644
index 0000000..cc55763
--- /dev/null
+++ b/extensions/geode-modules-tomcat9/src/test/java/org/apache/geode/modules/session/catalina/Tomcat9DeltaSessionManagerJUnitTest.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package org.apache.geode.modules.session.catalina;
+
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.LifecycleState;
+import org.apache.catalina.Pipeline;
+import org.junit.Before;
+import org.junit.Test;
+
+import org.apache.geode.internal.cache.GemFireCacheImpl;
+
+public class Tomcat9DeltaSessionManagerJUnitTest extends DeltaSessionManagerJUnitTest {
+  private Pipeline pipeline;
+
+  @Before
+  public void setup() {
+    manager = spy(new Tomcat9DeltaSessionManager());
+    initTest();
+    pipeline = mock(Pipeline.class);
+    doReturn(context).when(manager).getContext();
+  }
+
+  @Test
+  public void startInternalSucceedsInitialRun()
+      throws LifecycleException, IOException, ClassNotFoundException {
+    doNothing().when((Tomcat9DeltaSessionManager) manager).startInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+    doReturn(cache).when(manager).getAnyCacheInstance();
+    doReturn(true).when((GemFireCacheImpl) cache).isClient();
+    doNothing().when(manager).initSessionCache();
+    doReturn(pipeline).when(manager).getPipeline();
+
+    // Unit testing for load is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).load();
+
+    doNothing().when((Tomcat9DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STARTING);
+
+    assertThat(manager.started).isFalse();
+    ((Tomcat9DeltaSessionManager) manager).startInternal();
+    assertThat(manager.started).isTrue();
+    verify((Tomcat9DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+  }
+
+  @Test
+  public void startInternalDoesNotReinitializeManagerOnSubsequentCalls()
+      throws LifecycleException, IOException, ClassNotFoundException {
+    doNothing().when((Tomcat9DeltaSessionManager) manager).startInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+    doReturn(cache).when(manager).getAnyCacheInstance();
+    doReturn(true).when((GemFireCacheImpl) cache).isClient();
+    doNothing().when(manager).initSessionCache();
+    doReturn(pipeline).when(manager).getPipeline();
+
+    // Unit testing for load is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).load();
+
+    doNothing().when((Tomcat9DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STARTING);
+
+    assertThat(manager.started).isFalse();
+    ((Tomcat9DeltaSessionManager) manager).startInternal();
+
+    // Verify that various initialization actions were performed
+    assertThat(manager.started).isTrue();
+    verify(manager).initializeSessionCache();
+    verify((Tomcat9DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+
+    // Rerun startInternal
+    ((Tomcat9DeltaSessionManager) manager).startInternal();
+
+    // Verify that the initialization actions were still only performed one time
+    verify(manager).initializeSessionCache();
+    verify((Tomcat9DeltaSessionManager) manager).setLifecycleState(LifecycleState.STARTING);
+  }
+
+  @Test
+  public void stopInternal() throws LifecycleException, IOException {
+    doNothing().when((Tomcat9DeltaSessionManager) manager).startInternalBase();
+    doNothing().when((Tomcat9DeltaSessionManager) manager).destroyInternalBase();
+    doReturn(true).when(manager).isCommitValveEnabled();
+
+    // Unit testing for unload is handled in the parent DeltaSessionManagerJUnitTest class
+    doNothing().when(manager).unload();
+
+    doNothing().when((Tomcat9DeltaSessionManager) manager)
+        .setLifecycleState(LifecycleState.STOPPING);
+
+    ((Tomcat9DeltaSessionManager) manager).stopInternal();
+
+    assertThat(manager.started).isFalse();
+    verify((Tomcat9DeltaSessionManager) manager).setLifecycleState(LifecycleState.STOPPING);
+  }
+
+}
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionCache.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionCache.java
index 254bf57..f4aada3 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionCache.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/AbstractSessionCache.java
@@ -96,7 +96,7 @@
   }
 
   RegionConfiguration createRegionConfiguration() {
-    RegionConfiguration configuration = new RegionConfiguration();
+    RegionConfiguration configuration = getNewRegionConfiguration();
     configuration.setRegionName(getSessionManager().getRegionName());
     configuration.setRegionAttributesId(getSessionManager().getRegionAttributesId());
     if (getSessionManager()
@@ -110,4 +110,9 @@
     configuration.setEnableDebugListener(getSessionManager().getEnableDebugListener());
     return configuration;
   }
+
+  // Helper methods added to improve unit testing of class
+  RegionConfiguration getNewRegionConfiguration() {
+    return new RegionConfiguration();
+  }
 }
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/ClientServerSessionCache.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/ClientServerSessionCache.java
index 0803a4c..952e4cd 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/ClientServerSessionCache.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/ClientServerSessionCache.java
@@ -98,7 +98,7 @@
     // Invoke the appropriate function depending on the type of region
     if (regionAttributesID.startsWith("partition")) {
       // Execute the partitioned touch function on the primary server(s)
-      Execution execution = FunctionService.onRegion(getSessionRegion()).withFilter(sessionIds);
+      Execution execution = getExecutionForFunctionOnRegionWithFilter(sessionIds);
       try {
         ResultCollector collector = execution.execute(TouchPartitionedRegionEntriesFunction.ID);
         collector.getResult();
@@ -108,8 +108,8 @@
       }
     } else {
       // Execute the member touch function on all the server(s)
-      Execution execution = FunctionService.onServers(getCache())
-          .setArguments(new Object[] {this.sessionRegion.getFullPath(), sessionIds});
+      Object[] arguments = new Object[] {this.sessionRegion.getFullPath(), sessionIds};
+      Execution execution = getExecutionForFunctionOnServersWithArguments(arguments);
       try {
         ResultCollector collector = execution.execute(TouchReplicatedRegionEntriesFunction.ID);
         collector.getResult();
@@ -143,7 +143,7 @@
   @Override
   public boolean isBackingCacheAvailable() {
     if (getSessionManager().isCommitValveFailfastEnabled()) {
-      PoolImpl pool = (PoolImpl) PoolManager.find(getOperatingRegionName());
+      PoolImpl pool = findPoolInPoolManager();
       return pool.isPrimaryUpdaterAlive();
     }
     return true;
@@ -155,7 +155,7 @@
   }
 
   private void bootstrapServers() {
-    Execution execution = FunctionService.onServers(this.cache);
+    Execution execution = getExecutionForFunctionOnServers();
     ResultCollector collector = execution.execute(new BootstrappingFunction());
     // Get the result. Nothing is being done with it.
     try {
@@ -202,12 +202,12 @@
         .anyMatch(x -> x instanceof SessionExpirationCacheListener);
   }
 
-  private void createSessionRegionOnServers() {
+  void createSessionRegionOnServers() {
     // Create the RegionConfiguration
     RegionConfiguration configuration = createRegionConfiguration();
 
     // Send it to the server tier
-    Execution execution = FunctionService.onServer(this.cache).setArguments(configuration);
+    Execution execution = getExecutionForFunctionOnServerWithRegionConfiguration(configuration);
     ResultCollector collector = execution.execute(CreateRegionFunction.ID);
 
     // Verify the region was successfully created on the servers
@@ -225,7 +225,7 @@
     }
   }
 
-  private Region<String, HttpSession> createLocalSessionRegion() {
+  Region<String, HttpSession> createLocalSessionRegion() {
     ClientRegionFactory<String, HttpSession> factory = null;
     if (getSessionManager().getEnableLocalCache()) {
       // Create the region factory with caching and heap LRU enabled
@@ -257,4 +257,37 @@
 
     return region;
   }
+
+  // Helper methods added to improve unit testing of class
+  Execution getExecutionForFunctionOnServers() {
+    return getExecutionForFunctionOnServersWithArguments(null);
+  }
+
+  Execution getExecutionForFunctionOnServersWithArguments(Object[] arguments) {
+    if (arguments != null && arguments.length > 0) {
+      return FunctionService.onServers(getCache()).setArguments(arguments);
+    } else {
+      return FunctionService.onServers(getCache());
+    }
+  }
+
+  Execution getExecutionForFunctionOnServerWithRegionConfiguration(RegionConfiguration arguments) {
+    if (arguments != null) {
+      return FunctionService.onServer(getCache()).setArguments(arguments);
+    } else {
+      return FunctionService.onServer(getCache());
+    }
+  }
+
+  Execution getExecutionForFunctionOnRegionWithFilter(Set<?> filter) {
+    if (filter != null && filter.size() > 0) {
+      return FunctionService.onRegion(getSessionRegion()).withFilter(filter);
+    } else {
+      return FunctionService.onRegion(getSessionRegion());
+    }
+  }
+
+  PoolImpl findPoolInPoolManager() {
+    return (PoolImpl) PoolManager.find(getOperatingRegionName());
+  }
 }
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java
index 0be6d03..aa8b3f5 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSession.java
@@ -115,10 +115,9 @@
   @SuppressWarnings("unchecked")
   public HttpSession getSession() {
     if (facade == null) {
-      if (SecurityUtil.isPackageProtectionEnabled()) {
+      if (isPackageProtectionEnabled()) {
         final DeltaSession fsession = this;
-        facade = (DeltaSessionFacade) AccessController.doPrivileged(
-            (PrivilegedAction) () -> new DeltaSessionFacade(fsession));
+        facade = getNewFacade(fsession);
       } else {
         facade = new DeltaSessionFacade(this);
       }
@@ -191,7 +190,7 @@
     return this.operatingRegion;
   }
 
-  private boolean isCommitEnabled() {
+  boolean isCommitEnabled() {
     DeltaSessionManager mgr = (DeltaSessionManager) getManager();
     return mgr.isCommitValveEnabled();
   }
@@ -240,7 +239,9 @@
 
   @Override
   public void setAttribute(String name, Object value, boolean notify) {
+
     checkBackingCacheAvailable();
+
     synchronized (this.changeLock) {
       // Serialize the value
       byte[] serializedValue = serialize(value);
@@ -261,6 +262,7 @@
           new DeltaSessionUpdateAttributeEvent(name, serializedValue);
       queueAttributeEvent(event, true);
 
+
       // Distribute the update
       if (!isCommitEnabled()) {
         putInRegion(getOperatingRegion(), true, null);
@@ -318,6 +320,10 @@
     return value;
   }
 
+  Object getAttributeWithoutDeserialize(String name) {
+    return super.getAttribute(name);
+  }
+
   @Override
   public void invalidate() {
     super.invalidate();
@@ -414,7 +420,7 @@
         }
       }
     }
-    this.eventQueue.add(event);
+    addEventToEventQueue(event);
   }
 
   @SuppressWarnings("unchecked")
@@ -600,8 +606,8 @@
     @SuppressWarnings("unchecked")
     Enumeration<String> attributeNames = (Enumeration<String>) getAttributeNames();
     while (attributeNames.hasMoreElements()) {
-      // Don't use this.getAttribute() because we don't want to deserialize the value.
-      Object value = super.getAttribute(attributeNames.nextElement());
+      // Don't use getAttribute() because we don't want to deserialize the value.
+      Object value = getAttributeWithoutDeserialize(attributeNames.nextElement());
       if (value instanceof byte[]) {
         size += ((byte[]) value).length;
       }
@@ -634,10 +640,10 @@
     throw new IllegalStateException("Unable to access attributes field");
   }
 
-  private byte[] serialize(Object obj) {
+  byte[] serialize(Object obj) {
     byte[] serializedValue = null;
     try {
-      serializedValue = BlobHelper.serializeToBlob(obj);
+      serializedValue = serializeViaBlobHelper(obj);
     } catch (IOException e) {
       String builder = this + ": Object " + obj
           + " cannot be serialized due to the following exception";
@@ -647,6 +653,11 @@
     return serializedValue;
   }
 
+  byte[] serializeViaBlobHelper(Object obj) throws IOException {
+    return BlobHelper.serializeToBlob(obj);
+  }
+
+
   @Override
   public String toString() {
     return "DeltaSession[" + "id=" + getId()
@@ -655,4 +666,18 @@
         + (getOperatingRegion() == null ? "unset" : getOperatingRegion().getFullPath())
         + "]";
   }
+
+  // Helper methods to enable better unit testing
+  DeltaSessionFacade getNewFacade(DeltaSessionInterface fSession) {
+    return (DeltaSessionFacade) AccessController.doPrivileged(
+        (PrivilegedAction) () -> new DeltaSessionFacade(fSession));
+  }
+
+  boolean isPackageProtectionEnabled() {
+    return SecurityUtil.isPackageProtectionEnabled();
+  }
+
+  void addEventToEventQueue(DeltaSessionAttributeEvent event) {
+    eventQueue.add(event);
+  }
 }
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java
index be1142d..09dacde 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/DeltaSessionManager.java
@@ -29,6 +29,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -49,6 +50,7 @@
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 
+import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.CacheFactory;
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.query.Query;
@@ -63,6 +65,9 @@
 public abstract class DeltaSessionManager extends ManagerBase
     implements Lifecycle, PropertyChangeListener, SessionManager {
 
+  static final String catalinaBaseSystemProperty = "catalina.base";
+  static final String javaTempDirSystemProperty = "java.io.tmpdir";
+  static final String fileSeparatorSystemProperty = "file.separator";
   /**
    * The number of rejected sessions.
    */
@@ -372,7 +377,7 @@
 
   protected void initializeSessionCache() {
     // Retrieve the cache
-    GemFireCacheImpl cache = (GemFireCacheImpl) CacheFactory.getAnyInstance();
+    GemFireCacheImpl cache = (GemFireCacheImpl) getAnyCacheInstance();
     if (cache == null) {
       throw new IllegalStateException(
           "No cache exists. Please configure either a PeerToPeerCacheLifecycleListener or ClientServerCacheLifecycleListener in the server.xml file.");
@@ -383,9 +388,17 @@
         : new PeerToPeerSessionCache(this, cache);
 
     // Initialize the session cache
+    initSessionCache();
+  }
+
+  void initSessionCache() {
     this.sessionCache.initialize();
   }
 
+  Cache getAnyCacheInstance() {
+    return CacheFactory.getAnyInstance();
+  }
+
   @Override
   protected StandardSession getNewSession() {
     return new DeltaSession(this);
@@ -570,7 +583,7 @@
     getPipeline().addValve(jvmRouteBinderValve);
   }
 
-  protected Pipeline getPipeline() {
+  Pipeline getPipeline() {
     return getContainer().getPipeline();
   }
 
@@ -660,7 +673,7 @@
    * @throws IOException if an input/output error occurs
    */
   private void doUnload() throws IOException {
-    QueryService querySvc = sessionCache.getCache().getQueryService();
+    QueryService querySvc = getSessionCache().getCache().getQueryService();
     Context context = getTheContext();
 
     if (context == null) {
@@ -707,9 +720,9 @@
     ObjectOutputStream oos = null;
     boolean error = false;
     try {
-      fos = new FileOutputStream(store.getAbsolutePath());
-      bos = new BufferedOutputStream(fos);
-      oos = new ObjectOutputStream(bos);
+      fos = getFileOutputStream(store);
+      bos = getBufferedOutputStream(fos);
+      oos = getObjectOutputStream(bos);
     } catch (IOException e) {
       error = true;
       getLogger().error("Exception unloading sessions", e);
@@ -755,7 +768,7 @@
     if (getLogger().isDebugEnabled())
       getLogger().debug("Unloading " + list.size() + " sessions");
     try {
-      oos.writeObject(list.size());
+      writeToObjectOutputStream(oos, list);
       for (DeltaSessionInterface session : list) {
         if (session instanceof StandardSession) {
           StandardSession standardSession = (StandardSession) session;
@@ -830,8 +843,8 @@
     Loader loader = null;
     ClassLoader classLoader = null;
     try {
-      fis = new FileInputStream(store.getAbsolutePath());
-      bis = new BufferedInputStream(fis);
+      fis = getFileInputStream(store);
+      bis = getBufferedInputStream(fis);
       if (getTheContext() != null) {
         loader = getTheContext().getLoader();
       }
@@ -847,7 +860,7 @@
         if (getLogger().isDebugEnabled()) {
           getLogger().debug("Creating standard object input stream");
         }
-        ois = new ObjectInputStream(bis);
+        ois = getObjectInputStream(bis);
       }
     } catch (FileNotFoundException e) {
       if (getLogger().isDebugEnabled()) {
@@ -871,7 +884,7 @@
 
     // Load the previously unloaded active sessions
     try {
-      int n = (Integer) ois.readObject();
+      int n = getSessionCountFromObjectInputStream(ois);
       if (getLogger().isDebugEnabled()) {
         getLogger().debug("Loading " + n + " persisted sessions");
       }
@@ -932,16 +945,57 @@
    * Return a File object representing the pathname to our persistence file, if any.
    */
   private File sessionStore(String ctxPath) {
-    String storeDir = System.getProperty("catalina.base");
+    String storeDir = getSystemPropertyValue(catalinaBaseSystemProperty);
     if (storeDir == null || storeDir.isEmpty()) {
-      storeDir = System.getProperty("java.io.tmpdir");
+      storeDir = getSystemPropertyValue(javaTempDirSystemProperty);
     } else {
-      storeDir += System.getProperty("file.separator") + "temp";
+      storeDir += getSystemPropertyValue(fileSeparatorSystemProperty) + "temp";
     }
 
+    return getFileAtPath(storeDir, ctxPath);
+  }
+
+  String getSystemPropertyValue(String propertyKey) {
+    return System.getProperty(propertyKey);
+  }
+
+  File getFileAtPath(String storeDir, String ctxPath) {
     return (new File(storeDir, ctxPath.replaceAll("/", "_") + ".sessions.ser"));
   }
 
+  FileInputStream getFileInputStream(File file) throws FileNotFoundException {
+    return new FileInputStream(file.getAbsolutePath());
+  }
+
+  BufferedInputStream getBufferedInputStream(FileInputStream fis) {
+    return new BufferedInputStream(fis);
+  }
+
+  ObjectInputStream getObjectInputStream(BufferedInputStream bis) throws IOException {
+    return new ObjectInputStream(bis);
+  }
+
+  FileOutputStream getFileOutputStream(File file) throws FileNotFoundException {
+    return new FileOutputStream(file.getAbsolutePath());
+  }
+
+  BufferedOutputStream getBufferedOutputStream(FileOutputStream fos) {
+    return new BufferedOutputStream(fos);
+  }
+
+  ObjectOutputStream getObjectOutputStream(BufferedOutputStream bos) throws IOException {
+    return new ObjectOutputStream(bos);
+  }
+
+  void writeToObjectOutputStream(ObjectOutputStream oos, List listToWrite) throws IOException {
+    oos.writeObject(listToWrite.size());
+  }
+
+  int getSessionCountFromObjectInputStream(ObjectInputStream ois)
+      throws IOException, ClassNotFoundException {
+    return (Integer) ois.readObject();
+  }
+
   @Override
   public String toString() {
     return getClass().getSimpleName() + "[" + "container="
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/PeerToPeerSessionCache.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/PeerToPeerSessionCache.java
index 7d4b941..d5031c1 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/PeerToPeerSessionCache.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/session/catalina/PeerToPeerSessionCache.java
@@ -24,6 +24,7 @@
 import org.apache.geode.cache.RegionFactory;
 import org.apache.geode.cache.RegionShortcut;
 import org.apache.geode.cache.execute.Execution;
+import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionService;
 import org.apache.geode.cache.execute.ResultCollector;
 import org.apache.geode.modules.session.catalina.callback.LocalSessionCacheLoader;
@@ -87,12 +88,12 @@
     ResultCollector collector = null;
     if (regionAttributesID.startsWith("partition")) {
       // Execute the partitioned touch function on the primary server(s)
-      Execution execution = FunctionService.onRegion(getSessionRegion()).withFilter(sessionIds);
+      Execution execution = getExecutionForFunctionOnRegionWithFilter(sessionIds);
       collector = execution.execute(TouchPartitionedRegionEntriesFunction.ID);
     } else {
       // Execute the member touch function on all the server(s)
-      Execution execution = FunctionService.onMembers()
-          .setArguments(new Object[] {this.sessionRegion.getFullPath(), sessionIds});
+      Execution execution = getExecutionForFunctionOnMembersWithArguments(
+          new Object[] {this.sessionRegion.getFullPath(), sessionIds});
       collector = execution.execute(TouchReplicatedRegionEntriesFunction.ID);
     }
 
@@ -105,6 +106,7 @@
     }
   }
 
+
   @Override
   public boolean isPeerToPeer() {
     return true;
@@ -142,13 +144,13 @@
 
   private void registerFunctions() {
     // Register the touch partitioned region entries function if it is not already registered
-    if (!FunctionService.isRegistered(TouchPartitionedRegionEntriesFunction.ID)) {
-      FunctionService.registerFunction(new TouchPartitionedRegionEntriesFunction());
+    if (!isFunctionRegistered(TouchPartitionedRegionEntriesFunction.ID)) {
+      registerFunctionWithFunctionService(new TouchPartitionedRegionEntriesFunction());
     }
 
     // Register the touch replicated region entries function if it is not already registered
-    if (!FunctionService.isRegistered(TouchReplicatedRegionEntriesFunction.ID)) {
-      FunctionService.registerFunction(new TouchReplicatedRegionEntriesFunction());
+    if (!isFunctionRegistered(TouchReplicatedRegionEntriesFunction.ID)) {
+      registerFunctionWithFunctionService(new TouchReplicatedRegionEntriesFunction());
     }
   }
 
@@ -164,7 +166,7 @@
     Region region = this.cache.getRegion(getSessionManager().getRegionName());
     if (region == null) {
       // Create the region
-      region = RegionHelper.createRegion((Cache) getCache(), configuration);
+      region = createRegionUsingHelper(configuration);
       if (getSessionManager().getLogger().isDebugEnabled()) {
         getSessionManager().getLogger().debug("Created new session region: " + region);
       }
@@ -173,13 +175,21 @@
       if (getSessionManager().getLogger().isDebugEnabled()) {
         getSessionManager().getLogger().debug("Retrieved existing session region: " + region);
       }
-      RegionHelper.validateRegion((Cache) getCache(), configuration, region);
+      validateRegionUsingRegionhelper(configuration, region);
     }
 
     // Set the session region
     this.sessionRegion = region;
   }
 
+  void validateRegionUsingRegionhelper(RegionConfiguration configuration, Region region) {
+    RegionHelper.validateRegion((Cache) getCache(), configuration, region);
+  }
+
+  Region createRegionUsingHelper(RegionConfiguration configuration) {
+    return RegionHelper.createRegion((Cache) getCache(), configuration);
+  }
+
   private Region<String, HttpSession> createOrRetrieveLocalRegion() {
     // Attempt to retrieve the fronting region
     String frontingRegionName = this.sessionRegion.getName() + "_local";
@@ -215,4 +225,21 @@
     }
     return frontingRegion;
   }
+
+  // Helper methods added to improve unit testing of class
+  void registerFunctionWithFunctionService(Function function) {
+    FunctionService.registerFunction(function);
+  }
+
+  boolean isFunctionRegistered(String id) {
+    return FunctionService.isRegistered(id);
+  }
+
+  Execution getExecutionForFunctionOnRegionWithFilter(Set<String> sessionIds) {
+    return FunctionService.onRegion(getSessionRegion()).withFilter(sessionIds);
+  }
+
+  Execution getExecutionForFunctionOnMembersWithArguments(Object[] arguments) {
+    return FunctionService.onMembers().setArguments(arguments);
+  }
 }
diff --git a/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/TouchPartitionedRegionEntriesFunction.java b/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/TouchPartitionedRegionEntriesFunction.java
index 4f4049e..2fbeec5 100644
--- a/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/TouchPartitionedRegionEntriesFunction.java
+++ b/extensions/geode-modules/src/main/java/org/apache/geode/modules/util/TouchPartitionedRegionEntriesFunction.java
@@ -47,7 +47,7 @@
 
     Cache cache = context.getCache();
     // Get local (primary) data for the context
-    Region primaryDataSet = PartitionRegionHelper.getLocalDataForContext(rfc);
+    Region primaryDataSet = getLocalDataForContextViaRegionHelper(rfc);
 
     if (cache.getLogger().fineEnabled()) {
       String builder = "Function " + ID + " received request to touch "
@@ -96,4 +96,9 @@
 
   @Override
   public void fromData(DataInput in) {}
+
+  // Helper methods added to improve unit testing of class
+  Region getLocalDataForContextViaRegionHelper(RegionFunctionContext rfc) {
+    return PartitionRegionHelper.getLocalDataForContext(rfc);
+  }
 }
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerClusterTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerClusterTest.java
index d792b8c..7123a22 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerClusterTest.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerClusterTest.java
@@ -83,7 +83,7 @@
     Path functionsJarPath = temporaryFolder.getRoot().toPath()
         .resolve("functions.jar").toAbsolutePath();
     writeJarFromClasses(functionsJarPath.toFile(), GetFunctionExecutionTimerValues.class,
-        FunctionToTimeWithResult.class, ExecutionsTimerValues.class);
+        FunctionToTimeWithResult.class, ExecutionsTimerValues.class, ThreadSleep.class);
 
     String startLocatorCommand = String.join(" ",
         "start locator",
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerLonerTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerLonerTest.java
index 86a5ce3..14a18bc 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerLonerTest.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerLonerTest.java
@@ -89,7 +89,7 @@
     functionHelpersJarPath =
         temporaryFolder.getRoot().toPath().resolve("function-helpers.jar").toAbsolutePath();
     writeJarFromClasses(functionHelpersJarPath.toFile(), FunctionToTimeWithResult.class,
-        GetFunctionExecutionTimerValues.class, ExecutionsTimerValues.class);
+        GetFunctionExecutionTimerValues.class, ExecutionsTimerValues.class, ThreadSleep.class);
 
     startServerCommandWithStatsEnabled = startServerCommand(false, true);
     startServerCommandWithStatsDisabled = startServerCommand(true, true);
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerNoResultTest.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerNoResultTest.java
index 10e0347..7119b92 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerNoResultTest.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionExecutionsTimerNoResultTest.java
@@ -81,7 +81,7 @@
         .resolve("functions.jar").toAbsolutePath();
     writeJarFromClasses(functionsJarPath.toFile(),
         GetFunctionExecutionTimerValues.class, FunctionToTimeWithoutResult.class,
-        ExecutionsTimerValues.class);
+        ExecutionsTimerValues.class, ThreadSleep.class);
 
     String startLocatorCommand = String.join(" ",
         "start locator",
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithResult.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithResult.java
index 77180ac..82ba962 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithResult.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithResult.java
@@ -14,6 +14,9 @@
  */
 package org.apache.geode.metrics.function.executions;
 
+import static java.time.Duration.ofMillis;
+import static org.apache.geode.metrics.function.executions.ThreadSleep.sleepForAtLeast;
+
 import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.FunctionException;
@@ -24,13 +27,10 @@
   @Override
   public void execute(FunctionContext<String[]> context) {
     String[] arguments = context.getArguments();
-    long timeToSleep = Long.parseLong(arguments[0]);
+    long sleepTimeMillis = Long.parseLong(arguments[0]);
     boolean successful = Boolean.parseBoolean(arguments[1]);
 
-    try {
-      Thread.sleep(timeToSleep);
-    } catch (InterruptedException ignored) {
-    }
+    sleepForAtLeast(ofMillis(sleepTimeMillis));
 
     if (successful) {
       context.getResultSender().lastResult("OK");
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithoutResult.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithoutResult.java
index 64abced..685db05 100644
--- a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithoutResult.java
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/FunctionToTimeWithoutResult.java
@@ -14,6 +14,9 @@
  */
 package org.apache.geode.metrics.function.executions;
 
+import static java.time.Duration.ofMillis;
+import static org.apache.geode.metrics.function.executions.ThreadSleep.sleepForAtLeast;
+
 import org.apache.geode.cache.execute.Function;
 import org.apache.geode.cache.execute.FunctionContext;
 import org.apache.geode.cache.execute.FunctionException;
@@ -24,13 +27,10 @@
   @Override
   public void execute(FunctionContext<String[]> context) {
     String[] arguments = context.getArguments();
-    long timeToSleep = Long.parseLong(arguments[0]);
+    long sleepTimeMillis = Long.parseLong(arguments[0]);
     boolean successful = Boolean.parseBoolean(arguments[1]);
 
-    try {
-      Thread.sleep(timeToSleep);
-    } catch (InterruptedException ignored) {
-    }
+    sleepForAtLeast(ofMillis(sleepTimeMillis));
 
     if (!successful) {
       throw new FunctionException("FAIL");
diff --git a/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/ThreadSleep.java b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/ThreadSleep.java
new file mode 100644
index 0000000..807dc9c
--- /dev/null
+++ b/geode-assembly/src/acceptanceTest/java/org/apache/geode/metrics/function/executions/ThreadSleep.java
@@ -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.
+ */
+package org.apache.geode.metrics.function.executions;
+
+import static java.lang.Math.max;
+import static java.lang.System.nanoTime;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import java.time.Duration;
+
+class ThreadSleep {
+  private static final Duration MIN_TIME_TO_SLEEP = Duration.ofMillis(10);
+
+  /**
+   * Replacement for {@link Thread#sleep(long)} that sleeps at least as long as the given duration
+   *
+   * @param duration duration to sleep
+   */
+  static void sleepForAtLeast(Duration duration) {
+    long sleepTimeNanos = duration.toNanos();
+    long startTimeNanos = nanoTime();
+
+    while (true) {
+      long elapsedTimeNanos = nanoTime() - startTimeNanos;
+      if (elapsedTimeNanos >= sleepTimeNanos) {
+        break;
+      }
+
+      long remainingTimeNanos = sleepTimeNanos - elapsedTimeNanos;
+      try {
+        Thread.sleep(max(MIN_TIME_TO_SLEEP.toMillis(), NANOSECONDS.toMillis(remainingTimeNanos)));
+      } catch (InterruptedException ignored) {
+      }
+    }
+  }
+}
diff --git a/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerInstall.java b/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerInstall.java
index 62e05c3..a93e581 100644
--- a/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerInstall.java
+++ b/geode-assembly/src/distributedTest/java/org/apache/geode/session/tests/GenericAppServerInstall.java
@@ -33,7 +33,7 @@
  * specific code outside of the {@link GenericAppServerVersion}.
  */
 public class GenericAppServerInstall extends ContainerInstall {
-  private static final String JETTY_VERSION = "9.4.12.v20180830";
+  private static final String JETTY_VERSION = "9.4.21.v20190926";
 
   /**
    * Get the version number, download URL, and container name of a generic app server using
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 8e8a84a..40cecce 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -989,14 +989,14 @@
 lib/javax.transaction-api-1.3.jar
 lib/jaxb-api-2.3.1.jar
 lib/jaxb-impl-2.3.1.jar
-lib/jetty-http-9.4.12.v20180830.jar
-lib/jetty-io-9.4.12.v20180830.jar
-lib/jetty-security-9.4.12.v20180830.jar
-lib/jetty-server-9.4.12.v20180830.jar
-lib/jetty-servlet-9.4.12.v20180830.jar
-lib/jetty-util-9.4.12.v20180830.jar
-lib/jetty-webapp-9.4.12.v20180830.jar
-lib/jetty-xml-9.4.12.v20180830.jar
+lib/jetty-http-9.4.21.v20190926.jar
+lib/jetty-io-9.4.21.v20190926.jar
+lib/jetty-security-9.4.21.v20190926.jar
+lib/jetty-server-9.4.21.v20190926.jar
+lib/jetty-servlet-9.4.21.v20190926.jar
+lib/jetty-util-9.4.21.v20190926.jar
+lib/jetty-webapp-9.4.21.v20190926.jar
+lib/jetty-xml-9.4.21.v20190926.jar
 lib/jgroups-3.6.14.Final.jar
 lib/jline-2.12.jar
 lib/jna-4.1.0.jar
diff --git a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
index 1db9297..cfc23ac 100644
--- a/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
+++ b/geode-assembly/src/integrationTest/resources/dependency_classpath.txt
@@ -46,10 +46,10 @@
 micrometer-core-1.2.0.jar
 fastutil-8.2.2.jar
 javax.resource-api-1.7.1.jar
-jetty-webapp-9.4.12.v20180830.jar
-jetty-servlet-9.4.12.v20180830.jar
-jetty-security-9.4.12.v20180830.jar
-jetty-server-9.4.12.v20180830.jar
+jetty-webapp-9.4.21.v20190926.jar
+jetty-servlet-9.4.21.v20190926.jar
+jetty-security-9.4.21.v20190926.jar
+jetty-server-9.4.21.v20190926.jar
 javax.servlet-api-3.1.0.jar
 jna-4.1.0.jar
 jopt-simple-5.0.4.jar
@@ -71,10 +71,10 @@
 HdrHistogram-2.1.11.jar
 LatencyUtils-2.0.3.jar
 javax.transaction-api-1.3.jar
-jetty-xml-9.4.12.v20180830.jar
-jetty-http-9.4.12.v20180830.jar
-jetty-io-9.4.12.v20180830.jar
-jetty-util-9.4.12.v20180830.jar
+jetty-xml-9.4.21.v20190926.jar
+jetty-http-9.4.21.v20190926.jar
+jetty-io-9.4.21.v20190926.jar
+jetty-util-9.4.21.v20190926.jar
 commons-codec-1.10.jar
 lucene-analyzers-phonetic-6.6.2.jar
 lucene-analyzers-common-6.6.2.jar
diff --git a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModuleCanDoPutsTest.java b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModuleCanDoPutsTest.java
index 87f4295..3c9a7b5 100644
--- a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModuleCanDoPutsTest.java
+++ b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModuleCanDoPutsTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.session.tests;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.Parameterized;
 
@@ -27,6 +28,7 @@
     super(version);
   }
 
+  @Ignore // GEODE-7336 addressing failures in upgradeTests
   @Test
   public void test() throws Exception {
     startClusterWithTomcat(classPathTomcat7079);
diff --git a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java
index 411ab45..f38cfbf 100644
--- a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java
+++ b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.session.tests;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.Parameterized;
 
@@ -28,6 +29,7 @@
     super(version);
   }
 
+  @Ignore // GEODE-7336 addressing failures in upgradeTests
   @Test
   public void test() throws Exception {
     startClusterWithTomcat(classPathTomcat7079);
diff --git a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java
index 09f4937..f106af0 100644
--- a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java
+++ b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat7079WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.session.tests;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.Parameterized;
 
@@ -28,6 +29,7 @@
     super(version);
   }
 
+  @Ignore // GEODE-7336 addressing failures in upgradeTests
   @Test
   public void test() throws Exception {
     startClusterWithTomcat(classPathTomcat7079);
diff --git a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModuleCanDoPutsTest.java b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModuleCanDoPutsTest.java
index dbed04f..0acf089 100644
--- a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModuleCanDoPutsTest.java
+++ b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModuleCanDoPutsTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.session.tests;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.Parameterized;
 
@@ -27,6 +28,7 @@
     super(version);
   }
 
+  @Ignore // GEODE-7336 addressing failures in upgradeTests
   @Test
   public void test() throws Exception {
     startClusterWithTomcat(classPathTomcat8);
diff --git a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java
index de8dc4c..6064fe4 100644
--- a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java
+++ b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromCurrentModuleTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.session.tests;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.Parameterized;
 
@@ -28,6 +29,7 @@
     super(version);
   }
 
+  @Ignore // GEODE-7336 addressing failures in upgradeTests
   @Test
   public void test() throws Exception {
     startClusterWithTomcat(classPathTomcat8);
diff --git a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java
index e56755e..e40aaed 100644
--- a/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java
+++ b/geode-assembly/src/upgradeTest/java/org/apache/geode/session/tests/TomcatSessionBackwardsCompatibilityTomcat8WithOldModulesMixedWithCurrentCanDoPutFromOldModuleTest.java
@@ -14,6 +14,7 @@
  */
 package org.apache.geode.session.tests;
 
+import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runners.Parameterized;
 
@@ -28,6 +29,7 @@
     super(version);
   }
 
+  @Ignore // GEODE-7336 addressing failures in upgradeTests
   @Test
   public void test() throws Exception {
     startClusterWithTomcat(classPathTomcat8);
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/MBeanFederationErrorHandlingDistributedTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/MBeanFederationErrorHandlingDistributedTest.java
new file mode 100644
index 0000000..06be411
--- /dev/null
+++ b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/MBeanFederationErrorHandlingDistributedTest.java
@@ -0,0 +1,212 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.management.internal;
+
+import static org.apache.geode.cache.Region.SEPARATOR;
+import static org.apache.geode.cache.RegionShortcut.REPLICATE;
+import static org.apache.geode.distributed.ConfigurationProperties.HTTP_SERVICE_PORT;
+import static org.apache.geode.distributed.ConfigurationProperties.JMX_MANAGER_PORT;
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.management.internal.SystemManagementService.FEDERATING_MANAGER_FACTORY_PROPERTY;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.apache.geode.test.dunit.VM.getController;
+import static org.apache.geode.test.dunit.VM.getVM;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.concurrent.ExecutorService;
+
+import javax.management.ObjectName;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.stubbing.Answer;
+
+import org.apache.geode.StatisticsFactory;
+import org.apache.geode.cache.Cache;
+import org.apache.geode.cache.Region;
+import org.apache.geode.distributed.LocatorLauncher;
+import org.apache.geode.distributed.ServerLauncher;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.statistics.StatisticsClock;
+import org.apache.geode.management.ManagementService;
+import org.apache.geode.test.dunit.VM;
+import org.apache.geode.test.dunit.rules.DistributedRestoreSystemProperties;
+import org.apache.geode.test.dunit.rules.DistributedRule;
+import org.apache.geode.test.dunit.rules.SharedErrorCollector;
+import org.apache.geode.test.junit.categories.JMXTest;
+import org.apache.geode.test.junit.rules.serializable.SerializableTemporaryFolder;
+
+@Category(JMXTest.class)
+public class MBeanFederationErrorHandlingDistributedTest implements Serializable {
+
+  private static final String REGION_NAME = "test-region-1";
+
+  private static LocatorLauncher locatorLauncher;
+  private static ServerLauncher serverLauncher;
+  private static MBeanProxyFactory proxyFactory;
+
+  private ObjectName regionMXBeanName;
+  private String locatorName;
+  private String serverName;
+  private int locatorPort;
+  private VM locatorVM;
+  private VM serverVM;
+
+  @Rule
+  public DistributedRule distributedRule = new DistributedRule();
+
+  @Rule
+  public SharedErrorCollector errorCollector = new SharedErrorCollector();
+
+  @Rule
+  public DistributedRestoreSystemProperties restoreSystemProperties =
+      new DistributedRestoreSystemProperties();
+
+  @Rule
+  public SerializableTemporaryFolder temporaryFolder = new SerializableTemporaryFolder();
+
+  @Before
+  public void setUp() throws Exception {
+    locatorName = "locator";
+    serverName = "server";
+    regionMXBeanName =
+        new ObjectName(String.format("GemFire:service=Region,name=\"%s\",type=Member,member=%s",
+            SEPARATOR + REGION_NAME, serverName));
+
+    locatorVM = getController();
+    serverVM = getVM(0);
+
+    locatorPort = locatorVM.invoke(this::startLocator);
+
+    serverVM.invoke(this::startServer);
+  }
+
+  @After
+  public void tearDown() {
+    locatorVM.invoke(() -> {
+      if (locatorLauncher != null) {
+        locatorLauncher.stop();
+        locatorLauncher = null;
+        proxyFactory = null;
+      }
+    });
+
+    serverVM.invoke(() -> {
+      if (serverLauncher != null) {
+        serverLauncher.stop();
+        serverLauncher = null;
+      }
+    });
+  }
+
+  @Test
+  public void destroyMBeanBeforeFederationCompletes() {
+    locatorVM.invoke(() -> doAnswer((Answer<Void>) invocation -> {
+      serverVM.invoke(() -> {
+        Region region = serverLauncher.getCache().getRegion(REGION_NAME);
+        region.destroyRegion();
+      });
+
+      Region<String, Object> monitoringRegion = invocation.getArgument(2);
+      monitoringRegion.destroy(regionMXBeanName.toString());
+
+      assertThat(monitoringRegion.get(regionMXBeanName.toString())).isNull();
+
+      try {
+        invocation.callRealMethod();
+      } catch (Exception e) {
+        if (!locatorLauncher.getCache().isClosed()) {
+          errorCollector.addError(e);
+        }
+      }
+
+      return null;
+    })
+        .when(proxyFactory).createProxy(any(), eq(regionMXBeanName), any(), any()));
+
+    serverVM.invoke(() -> {
+      serverLauncher.getCache().createRegionFactory(REPLICATE).create(REGION_NAME);
+    });
+
+    locatorVM.invoke(() -> {
+      await().untilAsserted(
+          () -> verify(proxyFactory).createProxy(any(), eq(regionMXBeanName), any(), any()));
+    });
+  }
+
+  private int startLocator() throws IOException {
+    System.setProperty(FEDERATING_MANAGER_FACTORY_PROPERTY,
+        FederatingManagerFactoryWithSpy.class.getName());
+
+    locatorLauncher = new LocatorLauncher.Builder()
+        .setMemberName(locatorName)
+        .setPort(0)
+        .setWorkingDirectory(temporaryFolder.newFolder(locatorName).getAbsolutePath())
+        .set(HTTP_SERVICE_PORT, "0")
+        .set(JMX_MANAGER_PORT, "0")
+        .build();
+
+    locatorLauncher.start();
+
+    Cache cache = locatorLauncher.getCache();
+
+    SystemManagementService service =
+        (SystemManagementService) ManagementService.getManagementService(cache);
+    service.startManager();
+    FederatingManager federatingManager = service.getFederatingManager();
+    proxyFactory = federatingManager.getProxyFactory();
+
+    return locatorLauncher.getPort();
+  }
+
+  private void startServer() throws IOException {
+    serverLauncher = new ServerLauncher.Builder()
+        .setDisableDefaultServer(true)
+        .setMemberName(serverName)
+        .setWorkingDirectory(temporaryFolder.newFolder(serverName).getAbsolutePath())
+        .set(HTTP_SERVICE_PORT, "0")
+        .set(LOCATORS, "localHost[" + locatorPort + "]")
+        .build();
+
+    serverLauncher.start();
+  }
+
+  private static class FederatingManagerFactoryWithSpy implements FederatingManagerFactory {
+
+    public FederatingManagerFactoryWithSpy() {
+      // must be public for instantiation by reflection
+    }
+
+    @Override
+    public FederatingManager create(ManagementResourceRepo repo, InternalDistributedSystem system,
+        SystemManagementService service, InternalCache cache, StatisticsFactory statisticsFactory,
+        StatisticsClock statisticsClock, MBeanProxyFactory proxyFactory, MemberMessenger messenger,
+        ExecutorService executorService) {
+      return new FederatingManager(repo, system, service, cache, statisticsFactory,
+          statisticsClock, spy(proxyFactory), messenger, executorService);
+    }
+  }
+}
diff --git a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/MBeanFederationErrorPathDUnitTest.java b/geode-core/src/distributedTest/java/org/apache/geode/management/internal/MBeanFederationErrorPathDUnitTest.java
deleted file mode 100644
index f3f17b0..0000000
--- a/geode-core/src/distributedTest/java/org/apache/geode/management/internal/MBeanFederationErrorPathDUnitTest.java
+++ /dev/null
@@ -1,126 +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.
- */
-package org.apache.geode.management.internal;
-
-import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.spy;
-
-import java.rmi.RemoteException;
-
-import javax.management.MalformedObjectNameException;
-import javax.management.ObjectName;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import org.apache.geode.cache.Region;
-import org.apache.geode.cache.RegionShortcut;
-import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.management.ManagementService;
-import org.apache.geode.test.dunit.internal.InternalBlackboard;
-import org.apache.geode.test.dunit.internal.InternalBlackboardImpl;
-import org.apache.geode.test.dunit.rules.ClusterStartupRule;
-import org.apache.geode.test.dunit.rules.MemberVM;
-import org.apache.geode.test.junit.categories.JMXTest;
-import org.apache.geode.test.junit.rules.LocatorStarterRule;
-
-@Category({JMXTest.class})
-public class MBeanFederationErrorPathDUnitTest {
-  private static final int SERVER_1_VM_INDEX = 1;
-  private static final String REGION_NAME = "test-region-1";
-
-  public MemberVM server1, server2, server3;
-
-  @Rule
-  public LocatorStarterRule locator1 = new LocatorStarterRule();
-
-  @Rule
-  public ClusterStartupRule lsRule = new ClusterStartupRule();
-
-
-  private InternalBlackboard bb;
-
-  @Before
-  public void before() throws Exception {
-    locator1.withJMXManager().startLocator();
-
-    bb = InternalBlackboardImpl.getInstance();
-  }
-
-  @Test
-  public void destroyMBeanBeforeFederationCompletes()
-      throws MalformedObjectNameException, RemoteException {
-    String bbKey = "sync1";
-
-    String beanName = "GemFire:service=Region,name=\"/test-region-1\",type=Member,member=server-1";
-    ObjectName objectName = new ObjectName(beanName);
-
-    InternalCache cache = locator1.getCache();
-    SystemManagementService service =
-        (SystemManagementService) ManagementService.getManagementService(cache);
-    FederatingManager federatingManager = service.getFederatingManager();
-    MBeanProxyFactory mBeanProxyFactory = federatingManager.getProxyFactory();
-    MBeanProxyFactory spy = spy(mBeanProxyFactory);
-    service.getFederatingManager().setProxyFactory(spy);
-
-    Answer answer1 = new Answer<Object>() {
-      @Override
-      public Object answer(InvocationOnMock invocation) throws Throwable {
-        server1.invoke(() -> {
-          InternalCache serverCache = ClusterStartupRule.getCache();
-          Region region = serverCache.getRegionByPath("/" + REGION_NAME);
-          region.destroyRegion();
-        });
-
-        Region<String, Object> monitoringRegion = invocation.getArgument(2);
-        monitoringRegion.destroy(objectName.toString());
-
-        assertThat((monitoringRegion).get(objectName.toString())).isNull();
-
-        try {
-          invocation.callRealMethod();
-        } catch (Exception e) {
-          bb.setMailbox(bbKey, e);
-          return null;
-        }
-        bb.setMailbox(bbKey, "this is fine");
-        return null;
-      }
-    };
-
-    doAnswer(answer1).when(spy).createProxy(any(), eq(objectName), any(), any());
-
-    server1 = lsRule.startServerVM(SERVER_1_VM_INDEX, locator1.getPort());
-
-    server1.invoke(() -> {
-      InternalCache cache1 = ClusterStartupRule.getCache();
-      cache1.createRegionFactory(RegionShortcut.REPLICATE).create(REGION_NAME);
-    });
-
-    await().until(() -> bb.getMailbox(bbKey) != null);
-    Object e = bb.getMailbox("sync1");
-
-    assertThat(e).isNotInstanceOf(NullPointerException.class);
-    assertThat((String) e).contains("this is fine");
-  }
-}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/FederatingManagerIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/FederatingManagerIntegrationTest.java
deleted file mode 100644
index f5cbaad..0000000
--- a/geode-core/src/integrationTest/java/org/apache/geode/management/FederatingManagerIntegrationTest.java
+++ /dev/null
@@ -1,68 +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.
- */
-
-package org.apache.geode.management;
-
-import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import java.net.InetAddress;
-
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-
-import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.management.internal.FederatingManager;
-import org.apache.geode.management.internal.MemberMessenger;
-import org.apache.geode.management.internal.SystemManagementService;
-import org.apache.geode.test.junit.categories.JMXTest;
-import org.apache.geode.test.junit.rules.ServerStarterRule;
-
-@Category({JMXTest.class})
-public class FederatingManagerIntegrationTest {
-
-  @Rule
-  public ServerStarterRule serverRule = new ServerStarterRule();
-
-  @Test
-  public void testFederatingManagerConcurrency() throws Exception {
-    serverRule.startServer();
-    SystemManagementService service =
-        (SystemManagementService) ManagementService
-            .getExistingManagementService(serverRule.getCache());
-    service.createManager();
-    FederatingManager manager = service.getFederatingManager();
-
-    MemberMessenger messenger = mock(MemberMessenger.class);
-    manager.setMessenger(messenger);
-
-    manager.startManager();
-
-    InternalDistributedMember mockMember = mock(InternalDistributedMember.class);
-    when(mockMember.getInetAddress()).thenReturn(InetAddress.getLocalHost());
-    when(mockMember.getId()).thenReturn("member-1");
-
-    for (int i = 0; i < 100; i++) {
-      manager.addMember(mockMember);
-    }
-
-    await()
-        .until(() -> serverRule.getCache().getAllRegions().size() > 1);
-    assertThat(manager.getAndResetLatestException()).isNull();
-  }
-}
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/management/internal/FederatingManagerIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/FederatingManagerIntegrationTest.java
new file mode 100644
index 0000000..355e3ec
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/management/internal/FederatingManagerIntegrationTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more contributor license
+ * agreements. See the NOTICE file distributed with this work for additional information regarding
+ * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License. You may obtain a
+ * copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package org.apache.geode.management.internal;
+
+import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
+import static org.apache.geode.internal.net.SocketCreator.getLocalHost;
+import static org.apache.geode.management.internal.SystemManagementService.FEDERATING_MANAGER_FACTORY_PROPERTY;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.UnknownHostException;
+import java.util.concurrent.ExecutorService;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+
+import org.apache.geode.StatisticsFactory;
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.statistics.StatisticsClock;
+import org.apache.geode.management.ManagementService;
+import org.apache.geode.test.junit.categories.JMXTest;
+
+@Category(JMXTest.class)
+public class FederatingManagerIntegrationTest {
+
+  private InternalCache cache;
+  private FederatingManager federatingManager;
+
+  @Rule
+  public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+  @Before
+  public void setUp() {
+    System.setProperty(FEDERATING_MANAGER_FACTORY_PROPERTY,
+        FederatingManagerFactoryWithMockMessenger.class.getName());
+
+    cache = (InternalCache) new CacheFactory()
+        .set(LOCATORS, "")
+        .create();
+
+    SystemManagementService managementService =
+        (SystemManagementService) ManagementService.getExistingManagementService(cache);
+    managementService.createManager();
+    federatingManager = managementService.getFederatingManager();
+    federatingManager.startManager();
+  }
+
+  @After
+  public void tearDown() {
+    cache.close();
+  }
+
+  @Test
+  public void testFederatingManagerConcurrency() throws UnknownHostException {
+    InternalDistributedMember member = member();
+
+    for (int i = 1; i <= 100; i++) {
+      federatingManager.addMember(member);
+    }
+
+    await().until(() -> !cache.getAllRegions().isEmpty());
+
+    assertThat(federatingManager.getAndResetLatestException()).isNull();
+  }
+
+  private InternalDistributedMember member() throws UnknownHostException {
+    InternalDistributedMember member = mock(InternalDistributedMember.class);
+    when(member.getInetAddress()).thenReturn(getLocalHost());
+    when(member.getId()).thenReturn("member-1");
+    return member;
+  }
+
+  private static class FederatingManagerFactoryWithMockMessenger
+      implements FederatingManagerFactory {
+
+    public FederatingManagerFactoryWithMockMessenger() {
+      // must be public for instantiation by reflection
+    }
+
+    @Override
+    public FederatingManager create(ManagementResourceRepo repo, InternalDistributedSystem system,
+        SystemManagementService service, InternalCache cache, StatisticsFactory statisticsFactory,
+        StatisticsClock statisticsClock, MBeanProxyFactory proxyFactory, MemberMessenger messenger,
+        ExecutorService executorService) {
+      return new FederatingManager(repo, system, service, cache, statisticsFactory,
+          statisticsClock, proxyFactory, mock(MemberMessenger.class), executorService);
+    }
+  }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/cache/RegionDestroyedException.java b/geode-core/src/main/java/org/apache/geode/cache/RegionDestroyedException.java
index 66abcf8..7a748b1 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/RegionDestroyedException.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/RegionDestroyedException.java
@@ -18,15 +18,15 @@
  * Indicates that the region has been destroyed. Further operations on the region object are not
  * allowed.
  *
- *
  * @since GemFire 2.0
  */
 public class RegionDestroyedException extends CacheRuntimeException {
   private static final long serialVersionUID = 319804842308010754L;
-  private String regionFullPath;
+
+  private final String regionFullPath;
 
   /**
-   * Constructs a <code>RegionDestroyedException</code> with a message.
+   * Constructs a {@code RegionDestroyedException} with a message.
    *
    * @param msg the String message
    */
@@ -36,7 +36,7 @@
   }
 
   /**
-   * Constructs a <code>RegionDestroyedException</code> with a message and a cause.
+   * Constructs a {@code RegionDestroyedException} with a message and a cause.
    *
    * @param s the String message
    * @param ex the Throwable cause
@@ -47,6 +47,6 @@
   }
 
   public String getRegionFullPath() {
-    return this.regionFullPath;
+    return regionFullPath;
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/internal/monitoring/executor/AbstractExecutor.java b/geode-core/src/main/java/org/apache/geode/internal/monitoring/executor/AbstractExecutor.java
index 8f98926..0de7fa6 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/monitoring/executor/AbstractExecutor.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/monitoring/executor/AbstractExecutor.java
@@ -28,6 +28,7 @@
 
   private static final int THREAD_DUMP_DEPTH = 40;
   private static final Logger logger = LogService.getLogger();
+  public static final String LOCK_OWNER_THREAD_STACK = "Lock owner thread stack";
   private long threadID;
   private String groupName;
   private short numIterationsStuck;
@@ -47,10 +48,10 @@
 
   public void handleExpiry(long stuckTime) {
     this.incNumIterationsStuck();
-    logger.warn(handleLogMessage(stuckTime));
+    logger.warn(createThreadReport(stuckTime));
   }
 
-  private String handleLogMessage(long stuckTime) {
+  String createThreadReport(long stuckTime) {
 
     DateFormat dateFormat = new SimpleDateFormat("dd MMM yyyy HH:mm:ss zzz");
 
@@ -58,42 +59,57 @@
         ManagementFactory.getThreadMXBean().getThreadInfo(this.threadID, THREAD_DUMP_DEPTH);
     boolean logThreadDetails = (thread != null);
 
-    StringBuilder strb = new StringBuilder();
+    StringBuilder stringBuilder = new StringBuilder();
+    final String lineSeparator = System.lineSeparator();
 
-    strb.append("Thread <").append(this.threadID).append("> (0x")
+    stringBuilder.append("Thread <").append(this.threadID).append("> (0x")
         .append(Long.toHexString(this.threadID)).append(") that was executed at <")
         .append(dateFormat.format(this.getStartTime())).append("> has been stuck for <")
         .append((float) stuckTime / 1000)
         .append(" seconds> and number of thread monitor iteration <")
-        .append(this.numIterationsStuck).append("> ").append(System.lineSeparator());
+        .append(this.numIterationsStuck).append("> ").append(lineSeparator);
     if (logThreadDetails) {
-      strb.append("Thread Name <").append(thread.getThreadName()).append(">")
+      stringBuilder.append("Thread Name <").append(thread.getThreadName()).append(">")
           .append(" state <").append(thread.getThreadState())
-          .append(">").append(System.lineSeparator());
+          .append(">").append(lineSeparator);
 
       if (thread.getLockName() != null)
-        strb.append("Waiting on <").append(thread.getLockName()).append(">")
-            .append(System.lineSeparator());
+        stringBuilder.append("Waiting on <").append(thread.getLockName()).append(">")
+            .append(lineSeparator);
 
       if (thread.getLockOwnerName() != null)
-        strb.append("Owned By <").append(thread.getLockOwnerName()).append("> with ID <")
-            .append(thread.getLockOwnerId()).append(">").append(System.lineSeparator());
+        stringBuilder.append("Owned By <").append(thread.getLockOwnerName()).append("> with ID <")
+            .append(thread.getLockOwnerId()).append(">").append(lineSeparator);
     }
 
 
-    strb.append("Executor Group <").append(groupName).append(">").append(System.lineSeparator())
+    stringBuilder.append("Executor Group <").append(groupName).append(">").append(
+        lineSeparator)
         .append("Monitored metric <ResourceManagerStats.numThreadsStuck>")
-        .append(System.lineSeparator());
+        .append(lineSeparator);
 
     if (logThreadDetails) {
-      strb.append("Thread Stack:").append(System.lineSeparator());
-      for (int i = 0; i < thread.getStackTrace().length; i++) {
-        String row = thread.getStackTrace()[i].toString();
-        strb.append(row).append(System.lineSeparator());
+      writeThreadStack(thread, "Thread stack:", stringBuilder);
+    }
+
+    if (logThreadDetails && thread.getLockOwnerName() != null) {
+      ThreadInfo lockOwnerThread = ManagementFactory.getThreadMXBean()
+          .getThreadInfo(thread.getLockOwnerId(), THREAD_DUMP_DEPTH);
+      if (lockOwnerThread != null) {
+        writeThreadStack(lockOwnerThread, LOCK_OWNER_THREAD_STACK, stringBuilder);
       }
     }
 
-    return strb.toString();
+    return stringBuilder.toString();
+  }
+
+  private void writeThreadStack(ThreadInfo thread, String header, StringBuilder strb) {
+    final String lineSeparator = System.lineSeparator();
+    strb.append(header).append(lineSeparator);
+    for (int i = 0; i < thread.getStackTrace().length; i++) {
+      String row = thread.getStackTrace()[i].toString();
+      strb.append(row).append(lineSeparator);
+    }
   }
 
   public long getStartTime() {
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/FederatingManager.java b/geode-core/src/main/java/org/apache/geode/management/internal/FederatingManager.java
index ca735c0..c5168a2 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/FederatingManager.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/FederatingManager.java
@@ -40,6 +40,7 @@
 import org.apache.geode.cache.EvictionAttributes;
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.RegionAttributes;
+import org.apache.geode.cache.RegionDestroyedException;
 import org.apache.geode.cache.RegionExistsException;
 import org.apache.geode.cache.Scope;
 import org.apache.geode.cache.TimeoutException;
@@ -51,7 +52,6 @@
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.InternalRegionArguments;
 import org.apache.geode.internal.logging.LogService;
-import org.apache.geode.internal.logging.LoggingExecutors;
 import org.apache.geode.internal.statistics.StatisticsClock;
 import org.apache.geode.management.ManagementException;
 
@@ -65,7 +65,10 @@
  * @since GemFire 7.0
  */
 public class FederatingManager extends Manager {
-  public static final Logger logger = LogService.getLogger();
+  private static final Logger logger = LogService.getLogger();
+
+  private final SystemManagementService service;
+  private final AtomicReference<Exception> latestException = new AtomicReference<>();
 
   /**
    * This Executor uses a pool of thread to execute the member addition /removal tasks, This will
@@ -73,31 +76,19 @@
    * unbounded in practical situation as number of members will be a finite set at any given point
    * of time
    */
-  private ExecutorService pooledMembershipExecutor;
+  private final ExecutorService executorService;
+  private final MBeanProxyFactory proxyFactory;
+  private final MemberMessenger messenger;
 
-  /**
-   * Proxy factory is used to create , remove proxies
-   */
-  private MBeanProxyFactory proxyFactory;
-
-  private MemberMessenger messenger;
-
-  private final SystemManagementService service;
-
-  private final AtomicReference<Exception> latestException = new AtomicReference<>(null);
-
-  FederatingManager(MBeanJMXAdapter jmxAdapter, ManagementResourceRepo repo,
-      InternalDistributedSystem system, SystemManagementService service, InternalCache cache,
-      StatisticsFactory statisticsFactory, StatisticsClock statisticsClock) {
+  FederatingManager(ManagementResourceRepo repo, InternalDistributedSystem system,
+      SystemManagementService service, InternalCache cache, StatisticsFactory statisticsFactory,
+      StatisticsClock statisticsClock, MBeanProxyFactory proxyFactory, MemberMessenger messenger,
+      ExecutorService executorService) {
     super(repo, system, cache, statisticsFactory, statisticsClock);
     this.service = service;
-    proxyFactory = new MBeanProxyFactory(jmxAdapter, service);
-    messenger = new MemberMessenger(jmxAdapter, system);
-  }
-
-  @VisibleForTesting
-  void setProxyFactory(MBeanProxyFactory newProxyFactory) {
-    proxyFactory = newProxyFactory;
+    this.proxyFactory = proxyFactory;
+    this.messenger = messenger;
+    this.executorService = executorService;
   }
 
   /**
@@ -111,9 +102,6 @@
         logger.debug("Starting the Federating Manager.... ");
       }
 
-      pooledMembershipExecutor = LoggingExecutors.newFixedThreadPool("FederatingManager", true,
-          Runtime.getRuntime().availableProcessors());
-
       running = true;
       startManagingActivity();
       messenger.broadcastManagerInfo();
@@ -136,46 +124,13 @@
     stopManagingActivity();
   }
 
-  /**
-   * This method will be invoked whenever a member stops being a managing node. The
-   * {@code ManagementException} has to be handled by the caller.
-   */
-  private void stopManagingActivity() {
-    try {
-      pooledMembershipExecutor.shutdownNow();
-
-      for (DistributedMember distributedMember : repo.getMonitoringRegionMap().keySet()) {
-        removeMemberArtifacts(distributedMember, false);
-      }
-    } catch (Exception e) {
-      throw new ManagementException(e);
-    }
-  }
-
   @Override
   public boolean isRunning() {
     return running;
   }
 
-  /**
-   * This method will be invoked from MembershipListener which is registered when the member becomes
-   * a Management node.
-   *
-   * <p>
-   * This method will delegate task to another thread and exit, so that it wont block the membership
-   * listener
-   */
-  @VisibleForTesting
-  public void addMember(InternalDistributedMember member) {
-    GIITask giiTask = new GIITask(member);
-    executeTask(() -> {
-      try {
-        giiTask.call();
-      } catch (RuntimeException e) {
-        logger.warn("Error federating new member {}", member.getId(), e);
-        latestException.set(e);
-      }
-    });
+  public MemberMessenger getMessenger() {
+    return messenger;
   }
 
   /**
@@ -190,38 +145,6 @@
     executeTask(new RemoveMemberTask(member, crashed));
   }
 
-  private void executeTask(Runnable task) {
-    try {
-      pooledMembershipExecutor.execute(task);
-    } catch (RejectedExecutionException ignored) {
-      // Ignore, we are getting shutdown
-    }
-  }
-
-  private void removeMemberArtifacts(DistributedMember member, boolean crashed) {
-    Region<String, Object> proxyRegion = repo.getEntryFromMonitoringRegionMap(member);
-    Region<NotificationKey, Notification> notificationRegion =
-        repo.getEntryFromNotifRegionMap(member);
-
-    if (proxyRegion == null && notificationRegion == null) {
-      return;
-    }
-
-    repo.romoveEntryFromMonitoringRegionMap(member);
-    repo.removeEntryFromNotifRegionMap(member);
-
-    // If cache is closed all the regions would have been destroyed implicitly
-    if (!cache.isClosed()) {
-      proxyFactory.removeAllProxies(member, proxyRegion);
-      proxyRegion.localDestroyRegion();
-      notificationRegion.localDestroyRegion();
-    }
-
-    if (!system.getDistributedMember().equals(member)) {
-      service.memberDeparted((InternalDistributedMember) member, crashed);
-    }
-  }
-
   /**
    * This method will be invoked from MembershipListener which is registered when the member becomes
    * a Management node.
@@ -236,6 +159,66 @@
   }
 
   /**
+   * This will return the last updated time of the proxyMBean.
+   *
+   * @param objectName {@link ObjectName} of the MBean
+   *
+   * @return last updated time of the proxy
+   */
+  long getLastUpdateTime(ObjectName objectName) {
+    return proxyFactory.getLastUpdateTime(objectName);
+  }
+
+  /**
+   * Find a particular proxy instance for a {@link ObjectName}, {@link DistributedMember} and
+   * interface class If the proxy interface does not implement the given interface class a
+   * {@link ClassCastException} will be thrown
+   *
+   * @param objectName {@link ObjectName} of the MBean
+   * @param interfaceClass interface class implemented by proxy
+   *
+   * @return an instance of proxy exposing the given interface
+   */
+  <T> T findProxy(ObjectName objectName, Class<T> interfaceClass) {
+    return proxyFactory.findProxy(objectName, interfaceClass);
+  }
+
+  /**
+   * Find a set of proxies given a {@link DistributedMember}.
+   *
+   * @param member {@link DistributedMember}
+   *
+   * @return a set of {@link ObjectName}
+   */
+  Set<ObjectName> findAllProxies(DistributedMember member) {
+    return proxyFactory.findAllProxies(member);
+  }
+
+  /**
+   * This method will be invoked whenever a member stops being a managing node. The
+   * {@code ManagementException} has to be handled by the caller.
+   */
+  private void stopManagingActivity() {
+    try {
+      executorService.shutdownNow();
+
+      for (DistributedMember distributedMember : repo.getMonitoringRegionMap().keySet()) {
+        removeMemberArtifacts(distributedMember, false);
+      }
+    } catch (Exception e) {
+      throw new ManagementException(e);
+    }
+  }
+
+  private void executeTask(Runnable task) {
+    try {
+      executorService.execute(task);
+    } catch (RejectedExecutionException ignored) {
+      // Ignore, we are getting shutdown
+    }
+  }
+
+  /**
    * This method will be invoked when a node transitions from managed node to managing node This
    * method will block for all GIIs to be completed But each GII is given a specific time frame.
    * After that the task will be marked as cancelled.
@@ -255,7 +238,7 @@
         logger.debug("Management Resource creation started  : ");
       }
       List<Future<InternalDistributedMember>> futureTaskList =
-          pooledMembershipExecutor.invokeAll(giiTaskList);
+          executorService.invokeAll(giiTaskList);
 
       for (Future<InternalDistributedMember> futureTask : futureTaskList) {
         try {
@@ -301,60 +284,70 @@
   }
 
   /**
-   * For internal Use only
+   * This method will be invoked from MembershipListener which is registered when the member becomes
+   * a Management node.
+   *
+   * <p>
+   * This method will delegate task to another thread and exit, so that it wont block the membership
+   * listener
    */
   @VisibleForTesting
+  void addMember(InternalDistributedMember member) {
+    GIITask giiTask = new GIITask(member);
+    executeTask(() -> {
+      try {
+        giiTask.call();
+      } catch (RuntimeException e) {
+        logger.warn("Error federating new member {}", member.getId(), e);
+        latestException.set(e);
+      }
+    });
+  }
+
+  @VisibleForTesting
+  void removeMemberArtifacts(DistributedMember member, boolean crashed) {
+    Region<String, Object> monitoringRegion = repo.getEntryFromMonitoringRegionMap(member);
+    Region<NotificationKey, Notification> notificationRegion =
+        repo.getEntryFromNotifRegionMap(member);
+
+    if (monitoringRegion == null && notificationRegion == null) {
+      return;
+    }
+
+    repo.romoveEntryFromMonitoringRegionMap(member);
+    repo.removeEntryFromNotifRegionMap(member);
+
+    // If cache is closed all the regions would have been destroyed implicitly
+    if (!cache.isClosed()) {
+      try {
+        proxyFactory.removeAllProxies(member, monitoringRegion);
+      } catch (RegionDestroyedException ignore) {
+        // ignored
+      }
+      try {
+        monitoringRegion.localDestroyRegion();
+      } catch (RegionDestroyedException ignore) {
+        // ignored
+      }
+      try {
+        notificationRegion.localDestroyRegion();
+      } catch (RegionDestroyedException ignore) {
+        // ignored
+      }
+    }
+
+    if (!system.getDistributedMember().equals(member)) {
+      service.memberDeparted((InternalDistributedMember) member, crashed);
+    }
+  }
+
+  @VisibleForTesting
   public MBeanProxyFactory getProxyFactory() {
     return proxyFactory;
   }
 
-  /**
-   * This will return the last updated time of the proxyMBean.
-   *
-   * @param objectName {@link ObjectName} of the MBean
-   *
-   * @return last updated time of the proxy
-   */
-  long getLastUpdateTime(ObjectName objectName) {
-    return proxyFactory.getLastUpdateTime(objectName);
-  }
-
-  /**
-   * Find a particular proxy instance for a {@link ObjectName}, {@link DistributedMember} and
-   * interface class If the proxy interface does not implement the given interface class a
-   * {@link ClassCastException} will be thrown
-   *
-   * @param objectName {@link ObjectName} of the MBean
-   * @param interfaceClass interface class implemented by proxy
-   *
-   * @return an instance of proxy exposing the given interface
-   */
-  <T> T findProxy(ObjectName objectName, Class<T> interfaceClass) {
-    return proxyFactory.findProxy(objectName, interfaceClass);
-  }
-
-  /**
-   * Find a set of proxies given a {@link DistributedMember}.
-   *
-   * @param member {@link DistributedMember}
-   *
-   * @return a set of {@link ObjectName}
-   */
-  Set<ObjectName> findAllProxies(DistributedMember member) {
-    return proxyFactory.findAllProxies(member);
-  }
-
-  public MemberMessenger getMessenger() {
-    return messenger;
-  }
-
   @VisibleForTesting
-  public void setMessenger(MemberMessenger messenger) {
-    this.messenger = messenger;
-  }
-
-  @VisibleForTesting
-  public synchronized Exception getAndResetLatestException() {
+  synchronized Exception getAndResetLatestException() {
     return latestException.getAndSet(null);
   }
 
@@ -500,7 +493,7 @@
 
       // Before completing task intimate all listening ProxyListener which might send
       // notifications.
-      service.memberJoined((InternalDistributedMember) member);
+      service.memberJoined(member);
 
       // Send manager info to the added member
       messenger.sendManagerInfo(member);
@@ -538,7 +531,7 @@
 
     private final InternalDistributedMember member;
 
-    GIITask(InternalDistributedMember member) {
+    private GIITask(InternalDistributedMember member) {
       this.member = member;
     }
 
@@ -554,7 +547,7 @@
     private final DistributedMember member;
     private final boolean crashed;
 
-    RemoveMemberTask(DistributedMember member, boolean crashed) {
+    private RemoveMemberTask(DistributedMember member, boolean crashed) {
       this.member = member;
       this.crashed = crashed;
     }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/FederatingManagerFactory.java b/geode-core/src/main/java/org/apache/geode/management/internal/FederatingManagerFactory.java
new file mode 100644
index 0000000..ed2e62b
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/FederatingManagerFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.geode.management.internal;
+
+import java.util.concurrent.ExecutorService;
+
+import org.apache.geode.StatisticsFactory;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.statistics.StatisticsClock;
+
+@FunctionalInterface
+interface FederatingManagerFactory {
+
+  FederatingManager create(ManagementResourceRepo repo, InternalDistributedSystem system,
+      SystemManagementService service, InternalCache cache, StatisticsFactory statisticsFactory,
+      StatisticsClock statisticsClock, MBeanProxyFactory proxyFactory, MemberMessenger messenger,
+      ExecutorService executorService);
+}
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/Manager.java b/geode-core/src/main/java/org/apache/geode/management/internal/Manager.java
index 5962d29..7a48465 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/Manager.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/Manager.java
@@ -15,6 +15,7 @@
 package org.apache.geode.management.internal;
 
 import org.apache.geode.StatisticsFactory;
+import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.InternalCacheForClientAccess;
@@ -34,12 +35,12 @@
   /**
    * depicts whether this node is a Managing node or not
    */
-  protected volatile boolean running = false;
+  protected volatile boolean running;
 
   /**
    * depicts whether this node is a Managing node or not
    */
-  protected volatile boolean stopCacheOps = false;
+  protected volatile boolean stopCacheOps;
 
   /**
    * This is a single window to manipulate region resources for management
@@ -70,9 +71,7 @@
 
   public abstract void stopManager();
 
-  /**
-   * For internal use only
-   */
+  @VisibleForTesting
   public ManagementResourceRepo getManagementResourceRepo() {
     return repo;
   }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java
index 79d99d4..9ba9be1 100755
--- a/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/SystemManagementService.java
@@ -14,11 +14,17 @@
  */
 package org.apache.geode.management.internal;
 
+import static java.util.Arrays.asList;
+import static java.util.stream.Collectors.toSet;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.stream.Collectors;
+import java.util.concurrent.ExecutorService;
 
 import javax.management.Notification;
 import javax.management.ObjectName;
@@ -27,6 +33,8 @@
 
 import org.apache.geode.CancelException;
 import org.apache.geode.StatisticsFactory;
+import org.apache.geode.annotations.Immutable;
+import org.apache.geode.annotations.VisibleForTesting;
 import org.apache.geode.cache.execute.FunctionService;
 import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.DistributedSystemDisconnectedException;
@@ -36,6 +44,7 @@
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.InternalCacheForClientAccess;
 import org.apache.geode.internal.logging.LogService;
+import org.apache.geode.internal.logging.LoggingExecutors;
 import org.apache.geode.internal.statistics.StatisticsClock;
 import org.apache.geode.management.AlreadyRunningException;
 import org.apache.geode.management.AsyncEventQueueMXBean;
@@ -52,7 +61,6 @@
 import org.apache.geode.management.ManagerMXBean;
 import org.apache.geode.management.MemberMXBean;
 import org.apache.geode.management.RegionMXBean;
-import org.apache.geode.management.internal.beans.ManagementAdapter;
 import org.apache.geode.management.membership.MembershipEvent;
 import org.apache.geode.management.membership.MembershipListener;
 
@@ -65,53 +73,33 @@
 public class SystemManagementService extends BaseManagementService {
   private static final Logger logger = LogService.getLogger();
 
+  @Immutable
+  @VisibleForTesting
+  static final String FEDERATING_MANAGER_FACTORY_PROPERTY = "FEDERATING_MANAGER_FACTORY";
+
   /**
    * The concrete implementation of DistributedSystem that provides internal-only functionality.
    */
   private final InternalDistributedSystem system;
 
   /**
-   * core component for distribution
-   */
-  private LocalManager localManager;
-
-  /**
    * This is a notification hub to listen all the notifications emitted from all the MBeans in a
    * peer cache./cache server
    */
   private final NotificationHub notificationHub;
 
   /**
-   * whether the service is closed or not if cache is closed automatically this service will be
-   * closed
-   */
-  private volatile boolean closed = false;
-
-  /**
-   * has the management service has started yet
-   */
-  private volatile boolean isStarted = false;
-
-  /**
    * Adapter to interact with platform MBean server
    */
   private final MBeanJMXAdapter jmxAdapter;
 
   private final InternalCacheForClientAccess cache;
 
-  private FederatingManager federatingManager;
-
   private final ManagementAgent agent;
 
   private final ManagementResourceRepo repo;
 
   /**
-   * This membership listener will listen on membership events after the node has transformed into a
-   * Managing node.
-   */
-  private ManagementMembershipListener listener;
-
-  /**
    * Proxy aggregator to create aggregate MBeans e.g. DistributedSystem and DistributedRegion
    * GemFire comes with a default aggregator.
    */
@@ -122,19 +110,38 @@
 
   private final StatisticsFactory statisticsFactory;
   private final StatisticsClock statisticsClock;
+  private final FederatingManagerFactory federatingManagerFactory;
 
-  public static BaseManagementService newSystemManagementService(
+  /**
+   * whether the service is closed or not if cache is closed automatically this service will be
+   * closed
+   */
+  private volatile boolean closed;
+
+  /**
+   * has the management service has started yet
+   */
+  private volatile boolean isStarted;
+
+  private LocalManager localManager;
+
+  private FederatingManager federatingManager;
+
+  /**
+   * This membership listener will listen on membership events after the node has transformed into a
+   * Managing node.
+   */
+  private ManagementMembershipListener listener;
+
+  static BaseManagementService newSystemManagementService(
       InternalCacheForClientAccess cache) {
     return new SystemManagementService(cache).init();
   }
 
-  protected SystemManagementService(InternalCacheForClientAccess cache) {
+  private SystemManagementService(InternalCacheForClientAccess cache) {
     this.cache = cache;
-    this.system = cache.getInternalDistributedSystem();
-    // This is a safe check to ensure Management service does not start for a
-    // system which is disconnected.
-    // Most likely scenario when this will happen is when a cache is closed and we are at this
-    // point.
+    system = cache.getInternalDistributedSystem();
+
     if (!system.isConnected()) {
       throw new DistributedSystemDisconnectedException(
           "This connection to a distributed system has been disconnected.");
@@ -142,116 +149,49 @@
 
     statisticsFactory = system.getStatisticsManager();
     statisticsClock = cache.getStatisticsClock();
+    jmxAdapter = new MBeanJMXAdapter(system.getDistributedMember());
+    repo = new ManagementResourceRepo();
+    notificationHub = new NotificationHub(repo);
 
-    this.jmxAdapter = new MBeanJMXAdapter(this.system.getDistributedMember());
-    this.repo = new ManagementResourceRepo();
-
-    this.notificationHub = new NotificationHub(repo);
     if (system.getConfig().getJmxManager()) {
-      this.agent = new ManagementAgent(system.getConfig(), cache);
+      agent = new ManagementAgent(system.getConfig(), cache);
     } else {
-      this.agent = null;
+      agent = null;
     }
-    ManagementFunction function = new ManagementFunction(notificationHub);
-    FunctionService.registerFunction(function);
-    this.proxyListeners = new CopyOnWriteArrayList<>();
-  }
 
-  /**
-   * This method will initialize all the internal components for Management and Monitoring
-   *
-   * It will a)start an JMX connectorServer b) create a notification hub c)register the
-   * ManagementFunction
-   */
-  private SystemManagementService init() {
-    try {
-      this.localManager =
-          new LocalManager(repo, system, this, cache, statisticsFactory, statisticsClock);
-      this.localManager.startManager();
-      this.listener = new ManagementMembershipListener(this);
-      system.getDistributionManager().addMembershipListener(listener);
-      isStarted = true;
-      return this;
-    } catch (CancelException e) {
-      // Rethrow all CancelExceptions (fix for defect 46339)
-      throw e;
-    } catch (Exception e) {
-      // Wrap all other exceptions as ManagementExceptions
-      logger.error(e.getMessage(), e);
-      throw new ManagementException(e);
-    }
-  }
+    FunctionService.registerFunction(new ManagementFunction(notificationHub));
 
-  /**
-   * For internal Use only
-   */
-  public LocalManager getLocalManager() {
-    return localManager;
-  }
-
-  public NotificationHub getNotificationHub() {
-    return notificationHub;
-  }
-
-  public FederatingManager getFederatingManager() {
-    return federatingManager;
-  }
-
-  public MBeanJMXAdapter getJMXAdapter() {
-    return jmxAdapter;
-  }
-
-  public ManagementAgent getManagementAgent() {
-    return agent;
-  }
-
-  public boolean isStartedAndOpen() {
-    return isStarted && !closed && system.isConnected();
-  }
-
-  private void verifyManagementService() {
-    if (!isStarted) {
-      throw new ManagementException(
-          "Management Service Not Started Yet");
-    }
-    if (!system.isConnected()) {
-      throw new ManagementException(
-          "Not Connected To Distributed System");
-    }
-    if (closed) {
-      throw new ManagementException(
-          "Management Service Is Closed");
-    }
+    proxyListeners = new CopyOnWriteArrayList<>();
+    federatingManagerFactory = createFederatingManagerFactory();
   }
 
   @Override
   public void close() {
     synchronized (instances) {
       if (closed) {
-        // its a no op, hence not logging any exception
         return;
       }
+
       if (logger.isDebugEnabled()) {
         logger.debug("Closing Management Service");
       }
       if (listener != null && system.isConnected()) {
         system.getDistributionManager().removeMembershipListener(listener);
       }
-      // Stop the Federating Manager first . It will ensure MBeans are not getting federated.
-      // while un-registering
+      // Stop the Federating Manager first to avoid federating while un-registering
       if (federatingManager != null && federatingManager.isRunning()) {
         federatingManager.stopManager();
       }
-      this.notificationHub.cleanUpListeners();
+      notificationHub.cleanUpListeners();
       jmxAdapter.cleanJMXResource();
       if (localManager.isRunning()) {
         localManager.stopManager();
       }
-      if (this.agent != null && this.agent.isRunning()) {
-        this.agent.stopAgent();
+      if (agent != null && agent.isRunning()) {
+        agent.stopAgent();
       }
 
-      getInternalCache().getJmxManagerAdvisor().broadcastChange();
+      cache.getJmxManagerAdvisor().broadcastChange();
       instances.remove(cache);
       localManager = null;
       closed = true;
@@ -262,31 +202,28 @@
   public <T> void federate(ObjectName objectName, Class<T> interfaceClass,
       boolean notificationEmitter) {
     verifyManagementService();
-    if (!objectName.getDomain().equalsIgnoreCase(ManagementConstants.OBJECTNAME__DEFAULTDOMAIN)) {
-      throw new ManagementException(
-          "Not A GemFire Domain MBean, can not Federate");
-    }
 
+    if (!objectName.getDomain().equalsIgnoreCase(ManagementConstants.OBJECTNAME__DEFAULTDOMAIN)) {
+      throw new ManagementException("Not A GemFire Domain MBean, can not Federate");
+    }
     if (!jmxAdapter.isRegistered(objectName)) {
-      throw new ManagementException(
-          "MBean Not Registered In GemFire Domain");
+      throw new ManagementException("MBean Not Registered In GemFire Domain");
     }
     if (notificationEmitter && !jmxAdapter.hasNotificationSupport(objectName)) {
-      throw new ManagementException(
-          "MBean Does Not Have Notification Support");
+      throw new ManagementException("MBean Does Not Have Notification Support");
     }
 
     // All validation Passed. Now create the federation Component
     Object object = jmxAdapter.getMBeanObject(objectName);
-    FederationComponent fedComp =
+    FederationComponent federationComponent =
         new FederationComponent(object, objectName, interfaceClass, notificationEmitter);
-    if (ManagementAdapter.refreshOnInit.contains(interfaceClass)) {
-      fedComp.refreshObjectState(true);// Fixes 46387
+    if (asList(RegionMXBean.class, MemberMXBean.class).contains(interfaceClass)) {
+      federationComponent.refreshObjectState(true);
     }
-    localManager.markForFederation(objectName, fedComp);
+    localManager.markForFederation(objectName, federationComponent);
 
     if (isManager()) {
-      afterCreateProxy(objectName, interfaceClass, object, fedComp);
+      afterCreateProxy(objectName, interfaceClass, object, federationComponent);
     }
   }
 
@@ -302,8 +239,8 @@
     }
     if (federatingManager == null) {
       return 0;
-
-    } else if (!federatingManager.isRunning()) {
+    }
+    if (!federatingManager.isRunning()) {
       return 0;
     }
     if (jmxAdapter.isLocalMBean(objectName)) {
@@ -327,20 +264,6 @@
     return jmxAdapter.getLocalRegionMXBean(regionPath);
   }
 
-  public <T> T getMBeanProxy(ObjectName objectName, Class<T> interfaceClass) {
-    if (!isStartedAndOpen()) {
-      return null;
-    }
-    if (federatingManager == null) {
-      return null;
-
-    } else if (!federatingManager.isRunning()) {
-      return null;
-    }
-
-    return federatingManager.findProxy(objectName, interfaceClass);
-  }
-
   @Override
   public MemberMXBean getMemberMXBean() {
     return jmxAdapter.getMemberMXBean();
@@ -353,22 +276,21 @@
     }
     if (system.getDistributedMember().equals(member)) {
       return jmxAdapter.getLocalGemFireMBean().keySet();
-    } else {
-      if (federatingManager == null) {
-        return Collections.emptySet();
-
-      } else if (!federatingManager.isRunning()) {
-        return Collections.emptySet();
-      }
-      return federatingManager.findAllProxies(member);
     }
+    if (federatingManager == null) {
+      return Collections.emptySet();
+    }
+    if (!federatingManager.isRunning()) {
+      return Collections.emptySet();
+    }
+    return federatingManager.findAllProxies(member);
   }
 
   @Override
   public Set<ObjectName> getAsyncEventQueueMBeanNames(DistributedMember member) {
-    Set<ObjectName> mBeanNames = this.queryMBeanNames(member);
-    return mBeanNames.stream().filter(x -> "AsyncEventQueue".equals(x.getKeyProperty("service")))
-        .collect(Collectors.toSet());
+    return queryMBeanNames(member).stream()
+        .filter(x -> "AsyncEventQueue".equals(x.getKeyProperty("service")))
+        .collect(toSet());
   }
 
   @Override
@@ -377,24 +299,20 @@
     return jmxAdapter.registerMBean(object, objectName, false);
   }
 
-  public ObjectName registerInternalMBean(Object object, ObjectName objectName) {
-    verifyManagementService();
-    return jmxAdapter.registerMBean(object, objectName, true);
-  }
-
   @Override
   public void unregisterMBean(ObjectName objectName) {
     if (!isStartedAndOpen()) {
       return;
     }
+
     verifyManagementService();
 
     if (isManager()) {
-      FederationComponent removedObj = localManager.getFedComponents().get(objectName);
-      if (removedObj != null) { // only for MBeans local to Manager , not
-                                // proxies
-        afterRemoveProxy(objectName, removedObj.getInterfaceClass(), removedObj.getMBeanObject(),
-            removedObj);
+      FederationComponent removed = localManager.getFedComponents().get(objectName);
+      if (removed != null) {
+        // only for MBeans local to Manager, not proxies
+        afterRemoveProxy(objectName, removed.getInterfaceClass(), removed.getMBeanObject(),
+            removed);
       }
     }
 
@@ -407,19 +325,16 @@
     return isManagerCreated() && federatingManager.isRunning();
   }
 
-  public boolean isManagerCreated() {
-    return isStartedAndOpen() && federatingManager != null;
-  }
-
   @Override
   public void startManager() {
-    if (!getInternalCache().getInternalDistributedSystem().getConfig().getJmxManager()) {
-      // fix for 45900
+    if (!cache.getInternalDistributedSystem().getConfig().getJmxManager()) {
       throw new ManagementException(
           "Could not start the manager because the gemfire property \"jmx-manager\" is false.");
     }
+
     synchronized (instances) {
       verifyManagementService();
+
       if (federatingManager != null && federatingManager.isRunning()) {
         throw new AlreadyRunningException(
             "Manager is already running");
@@ -432,15 +347,16 @@
       } else if (!federatingManager.isRunning()) {
         needsToBeStarted = true;
       }
+
       if (needsToBeStarted) {
         boolean started = false;
         try {
           system.handleResourceEvent(ResourceEvent.MANAGER_START, null);
           federatingManager.startManager();
-          if (this.agent != null) {
-            this.agent.startAgent();
+          if (agent != null) {
+            agent.startAgent();
           }
-          getInternalCache().getJmxManagerAdvisor().broadcastChange();
+          cache.getJmxManagerAdvisor().broadcastChange();
           started = true;
         } catch (RuntimeException | Error e) {
           logger.error("Jmx manager could not be started because {}", e.getMessage(), e);
@@ -457,27 +373,6 @@
     }
   }
 
-  private InternalCache getInternalCache() {
-    return this.cache;
-  }
-
-  /**
-   * Creates a Manager instance in stopped state.
-   */
-  public boolean createManager() {
-    synchronized (instances) {
-      if (federatingManager != null) {
-        return false;
-      }
-      system.handleResourceEvent(ResourceEvent.MANAGER_CREATE, null);
-      // An initialised copy of federating manager
-      federatingManager = new FederatingManager(jmxAdapter, repo, system, this, cache,
-          statisticsFactory, statisticsClock);
-      getInternalCache().getJmxManagerAdvisor().broadcastChange();
-      return true;
-    }
-  }
-
   /**
    * It will stop the federating Manager and restart the Local cache operation
    */
@@ -488,9 +383,9 @@
       if (federatingManager != null) {
         federatingManager.stopManager();
         system.handleResourceEvent(ResourceEvent.MANAGER_STOP, null);
-        getInternalCache().getJmxManagerAdvisor().broadcastChange();
-        if (this.agent != null && this.agent.isRunning()) {
-          this.agent.stopAgent();
+        cache.getJmxManagerAdvisor().broadcastChange();
+        if (agent != null && agent.isRunning()) {
+          agent.stopAgent();
         }
       }
     }
@@ -516,18 +411,6 @@
     return jmxAdapter.getDistributedSystemMXBean();
   }
 
-  public void addProxyListener(ProxyListener listener) {
-    this.proxyListeners.add(listener);
-  }
-
-  public void removeProxyListener(ProxyListener listener) {
-    this.proxyListeners.remove(listener);
-  }
-
-  public List<ProxyListener> getProxyListeners() {
-    return this.proxyListeners;
-  }
-
   @Override
   public ManagerMXBean getManagerMXBean() {
     return jmxAdapter.getManagerMXBean();
@@ -618,36 +501,102 @@
     return jmxAdapter.getLocatorMXBean();
   }
 
-  public boolean afterCreateProxy(ObjectName objectName, Class interfaceClass, Object proxyObject,
+  @Override
+  public <T> T getMBeanInstance(ObjectName objectName, Class<T> interfaceClass) {
+    if (jmxAdapter.isLocalMBean(objectName)) {
+      return jmxAdapter.findMBeanByName(objectName, interfaceClass);
+    }
+    return getMBeanProxy(objectName, interfaceClass);
+  }
+
+  @Override
+  public void addMembershipListener(MembershipListener listener) {
+    universalListenerContainer.addMembershipListener(listener);
+  }
+
+  @Override
+  public void removeMembershipListener(MembershipListener listener) {
+    universalListenerContainer.removeMembershipListener(listener);
+  }
+
+  public LocalManager getLocalManager() {
+    return localManager;
+  }
+
+  public FederatingManager getFederatingManager() {
+    return federatingManager;
+  }
+
+  public MBeanJMXAdapter getJMXAdapter() {
+    return jmxAdapter;
+  }
+
+  public ManagementAgent getManagementAgent() {
+    return agent;
+  }
+
+  public <T> T getMBeanProxy(ObjectName objectName, Class<T> interfaceClass) {
+    if (!isStartedAndOpen()) {
+      return null;
+    }
+    if (federatingManager == null) {
+      return null;
+    }
+    if (!federatingManager.isRunning()) {
+      return null;
+    }
+    return federatingManager.findProxy(objectName, interfaceClass);
+  }
+
+  public ObjectName registerInternalMBean(Object object, ObjectName objectName) {
+    verifyManagementService();
+    return jmxAdapter.registerMBean(object, objectName, true);
+  }
+
+  public boolean isManagerCreated() {
+    return isStartedAndOpen() && federatingManager != null;
+  }
+
+  /**
+   * Creates a Manager instance in stopped state.
+   */
+  public boolean createManager() {
+    synchronized (instances) {
+      if (federatingManager != null) {
+        return false;
+      }
+      system.handleResourceEvent(ResourceEvent.MANAGER_CREATE, null);
+      // An initialised copy of federating manager
+      federatingManager = federatingManagerFactory.create(repo, system, this, cache,
+          statisticsFactory, statisticsClock, new MBeanProxyFactory(jmxAdapter, this),
+          new MemberMessenger(jmxAdapter, system),
+          LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+              Runtime.getRuntime().availableProcessors()));
+      cache.getJmxManagerAdvisor().broadcastChange();
+      return true;
+    }
+  }
+
+  public void addProxyListener(ProxyListener listener) {
+    proxyListeners.add(listener);
+  }
+
+  public void removeProxyListener(ProxyListener listener) {
+    proxyListeners.remove(listener);
+  }
+
+  public void afterCreateProxy(ObjectName objectName, Class interfaceClass, Object proxyObject,
       FederationComponent newVal) {
     for (ProxyListener listener : proxyListeners) {
       listener.afterCreateProxy(objectName, interfaceClass, proxyObject, newVal);
     }
-    return true;
   }
 
-  public boolean afterPseudoCreateProxy(ObjectName objectName, Class interfaceClass,
-      Object proxyObject, FederationComponent newVal) {
-    for (ProxyListener listener : proxyListeners) {
-      listener.afterPseudoCreateProxy(objectName, interfaceClass, proxyObject, newVal);
-    }
-    return true;
-  }
-
-  public boolean afterRemoveProxy(ObjectName objectName, Class interfaceClass, Object proxyObject,
+  public void afterRemoveProxy(ObjectName objectName, Class interfaceClass, Object proxyObject,
       FederationComponent oldVal) {
     for (ProxyListener listener : proxyListeners) {
       listener.afterRemoveProxy(objectName, interfaceClass, proxyObject, oldVal);
     }
-    return true;
-  }
-
-  public boolean afterUpdateProxy(ObjectName objectName, Class interfaceClass, Object proxyObject,
-      FederationComponent newVal, FederationComponent oldVal) {
-    for (ProxyListener listener : proxyListeners) {
-      listener.afterUpdateProxy(objectName, interfaceClass, proxyObject, newVal, oldVal);
-    }
-    return true;
   }
 
   public void handleNotification(Notification notification) {
@@ -656,52 +605,133 @@
     }
   }
 
-  @Override
-  public <T> T getMBeanInstance(ObjectName objectName, Class<T> interfaceClass) {
-    if (jmxAdapter.isLocalMBean(objectName)) {
-      return jmxAdapter.findMBeanByName(objectName, interfaceClass);
-    } else {
-      return this.getMBeanProxy(objectName, interfaceClass);
-    }
-  }
-
-  public void logFine(String s) {
-    if (logger.isDebugEnabled()) {
-      logger.debug(s);
-    }
-  }
-
-  public void memberJoined(InternalDistributedMember id) {
+  void memberJoined(InternalDistributedMember id) {
     for (ProxyListener listener : proxyListeners) {
       listener.memberJoined(system.getDistributionManager(), id);
     }
   }
 
-  public void memberDeparted(InternalDistributedMember id, boolean crashed) {
+  void memberDeparted(InternalDistributedMember id, boolean crashed) {
     for (ProxyListener listener : proxyListeners) {
       listener.memberDeparted(system.getDistributionManager(), id, crashed);
     }
   }
 
-  public void memberSuspect(InternalDistributedMember id, InternalDistributedMember whoSuspected,
+  void memberSuspect(InternalDistributedMember id, InternalDistributedMember whoSuspected,
       String reason) {
     for (ProxyListener listener : proxyListeners) {
       listener.memberSuspect(system.getDistributionManager(), id, whoSuspected, reason);
     }
   }
 
-  public void quorumLost(Set<InternalDistributedMember> failures,
-      List<InternalDistributedMember> remaining) {
+  void afterPseudoCreateProxy(ObjectName objectName, Class interfaceClass, Object proxyObject,
+      FederationComponent newVal) {
     for (ProxyListener listener : proxyListeners) {
-      listener.quorumLost(system.getDistributionManager(), failures, remaining);
+      listener.afterPseudoCreateProxy(objectName, interfaceClass, proxyObject, newVal);
     }
   }
 
-  public static class UniversalListenerContainer {
+  boolean isStartedAndOpen() {
+    return isStarted && !closed && system.isConnected();
+  }
 
-    private List<MembershipListener> membershipListeners = new CopyOnWriteArrayList<>();
+  void afterUpdateProxy(ObjectName objectName, Class interfaceClass, Object proxyObject,
+      FederationComponent newVal, FederationComponent oldVal) {
+    for (ProxyListener listener : proxyListeners) {
+      listener.afterUpdateProxy(objectName, interfaceClass, proxyObject, newVal, oldVal);
+    }
+  }
 
-    public void memberJoined(InternalDistributedMember id) {
+  UniversalListenerContainer getUniversalListenerContainer() {
+    return universalListenerContainer;
+  }
+
+  private void verifyManagementService() {
+    if (!isStarted) {
+      throw new ManagementException(
+          "Management Service Not Started Yet");
+    }
+    if (!system.isConnected()) {
+      throw new ManagementException(
+          "Not Connected To Distributed System");
+    }
+    if (closed) {
+      throw new ManagementException(
+          "Management Service Is Closed");
+    }
+  }
+
+  /**
+   * This method will initialize all the internal components for Management and Monitoring
+   *
+   * It will: <br>
+   * a) start an JMX connectorServer <br>
+   * b) create a notification hub <br>
+   * c) register the ManagementFunction
+   */
+  private SystemManagementService init() {
+    try {
+      localManager =
+          new LocalManager(repo, system, this, cache, statisticsFactory, statisticsClock);
+      listener = new ManagementMembershipListener(this);
+
+      localManager.startManager();
+      system.getDistributionManager().addMembershipListener(listener);
+      isStarted = true;
+      return this;
+    } catch (CancelException e) {
+      // Rethrow all CancelExceptions
+      throw e;
+    } catch (Exception e) {
+      // Wrap all other exceptions as ManagementExceptions
+      logger.error(e.getMessage(), e);
+      throw new ManagementException(e);
+    }
+  }
+
+  private static FederatingManagerFactory createFederatingManagerFactory() {
+    try {
+      String federatingManagerFactoryName =
+          System.getProperty(FEDERATING_MANAGER_FACTORY_PROPERTY,
+              FederatingManagerFactoryImpl.class.getName());
+      Class<? extends FederatingManagerFactory> federatingManagerFactoryClass =
+          Class.forName(federatingManagerFactoryName)
+              .asSubclass(FederatingManagerFactory.class);
+      Constructor<? extends FederatingManagerFactory> constructor =
+          federatingManagerFactoryClass.getConstructor();
+      return constructor.newInstance();
+    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException
+        | NoSuchMethodException | InvocationTargetException e) {
+      return new FederatingManagerFactoryImpl();
+    }
+  }
+
+  @VisibleForTesting
+  public NotificationHub getNotificationHub() {
+    return notificationHub;
+  }
+
+  private static class FederatingManagerFactoryImpl implements FederatingManagerFactory {
+
+    public FederatingManagerFactoryImpl() {
+      // must be public for instantiation by reflection
+    }
+
+    @Override
+    public FederatingManager create(ManagementResourceRepo repo, InternalDistributedSystem system,
+        SystemManagementService service, InternalCache cache, StatisticsFactory statisticsFactory,
+        StatisticsClock statisticsClock, MBeanProxyFactory proxyFactory, MemberMessenger messenger,
+        ExecutorService executorService) {
+      return new FederatingManager(repo, system, service, cache, statisticsFactory,
+          statisticsClock, proxyFactory, messenger, executorService);
+    }
+  }
+
+  static class UniversalListenerContainer {
+
+    private final Collection<MembershipListener> membershipListeners = new CopyOnWriteArrayList<>();
+
+    void memberJoined(InternalDistributedMember id) {
       MembershipEvent event = createEvent(id);
       for (MembershipListener listener : membershipListeners) {
         try {
@@ -713,18 +743,9 @@
       }
     }
 
-    public void memberDeparted(InternalDistributedMember id, boolean crashed) {
+    void memberDeparted(InternalDistributedMember id, boolean crashed) {
       MembershipEvent event = createEvent(id);
-      if (!crashed) {
-        for (MembershipListener listener : membershipListeners) {
-          try {
-            listener.memberLeft(event);
-          } catch (Exception e) {
-            logger.error("Could not invoke listener event memberLeft for listener[{}] due to ",
-                listener.getClass(), e.getMessage(), e);
-          }
-        }
-      } else {
+      if (crashed) {
         for (MembershipListener listener : membershipListeners) {
           try {
             listener.memberCrashed(event);
@@ -733,32 +754,23 @@
                 listener.getClass(), e.getMessage(), e);
           }
         }
+      } else {
+        for (MembershipListener listener : membershipListeners) {
+          try {
+            listener.memberLeft(event);
+          } catch (Exception e) {
+            logger.error("Could not invoke listener event memberLeft for listener[{}] due to ",
+                listener.getClass(), e.getMessage(), e);
+          }
+        }
       }
     }
 
-    private MembershipEvent createEvent(InternalDistributedMember id) {
-      final String memberId = id.getId();
-      final DistributedMember member = id;
-
-      return new MembershipEvent() {
-
-        @Override
-        public String getMemberId() {
-          return memberId;
-        }
-
-        @Override
-        public DistributedMember getDistributedMember() {
-          return member;
-        }
-      };
-    }
-
     /**
      * Registers a listener that receives call backs when a member joins or leaves the distributed
      * system.
      */
-    public void addMembershipListener(MembershipListener listener) {
+    private void addMembershipListener(MembershipListener listener) {
       membershipListeners.add(listener);
     }
 
@@ -767,23 +779,23 @@
      *
      * @see #addMembershipListener
      */
-    public void removeMembershipListener(MembershipListener listener) {
+    private void removeMembershipListener(MembershipListener listener) {
       membershipListeners.remove(listener);
     }
-  }
 
-  public UniversalListenerContainer getUniversalListenerContainer() {
-    return universalListenerContainer;
-  }
+    private MembershipEvent createEvent(DistributedMember id) {
+      return new MembershipEvent() {
 
-  @Override
-  public void addMembershipListener(MembershipListener listener) {
-    universalListenerContainer.addMembershipListener(listener);
+        @Override
+        public String getMemberId() {
+          return id.getId();
+        }
 
-  }
-
-  @Override
-  public void removeMembershipListener(MembershipListener listener) {
-    universalListenerContainer.removeMembershipListener(listener);
+        @Override
+        public DistributedMember getDistributedMember() {
+          return id;
+        }
+      };
+    }
   }
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementAdapter.java b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementAdapter.java
index 1327d6f..bd8702b 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementAdapter.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementAdapter.java
@@ -14,9 +14,68 @@
  */
 package org.apache.geode.management.internal.beans;
 
+import static java.util.Arrays.asList;
+import static java.util.Collections.unmodifiableList;
+import static org.apache.commons.lang3.StringUtils.isNotBlank;
+import static org.apache.geode.management.JMXNotificationType.ASYNC_EVENT_QUEUE_CLOSED;
+import static org.apache.geode.management.JMXNotificationType.ASYNC_EVENT_QUEUE_CREATED;
+import static org.apache.geode.management.JMXNotificationType.CACHE_SERVER_STARTED;
+import static org.apache.geode.management.JMXNotificationType.CACHE_SERVER_STOPPED;
+import static org.apache.geode.management.JMXNotificationType.CACHE_SERVICE_CREATED;
+import static org.apache.geode.management.JMXNotificationType.CLIENT_CRASHED;
+import static org.apache.geode.management.JMXNotificationType.CLIENT_JOINED;
+import static org.apache.geode.management.JMXNotificationType.CLIENT_LEFT;
+import static org.apache.geode.management.JMXNotificationType.DISK_STORE_CLOSED;
+import static org.apache.geode.management.JMXNotificationType.DISK_STORE_CREATED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_RECEIVER_CREATED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_RECEIVER_DESTROYED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_RECEIVER_STARTED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_RECEIVER_STOPPED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_SENDER_CREATED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_SENDER_PAUSED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_SENDER_REMOVED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_SENDER_RESUMED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_SENDER_STARTED;
+import static org.apache.geode.management.JMXNotificationType.GATEWAY_SENDER_STOPPED;
+import static org.apache.geode.management.JMXNotificationType.LOCATOR_STARTED;
+import static org.apache.geode.management.JMXNotificationType.LOCK_SERVICE_CLOSED;
+import static org.apache.geode.management.JMXNotificationType.LOCK_SERVICE_CREATED;
+import static org.apache.geode.management.JMXNotificationType.REGION_CLOSED;
+import static org.apache.geode.management.JMXNotificationType.REGION_CREATED;
+import static org.apache.geode.management.JMXNotificationType.SYSTEM_ALERT;
+import static org.apache.geode.management.JMXNotificationUserData.ALERT_LEVEL;
+import static org.apache.geode.management.JMXNotificationUserData.MEMBER;
+import static org.apache.geode.management.JMXNotificationUserData.THREAD;
+import static org.apache.geode.management.internal.AlertDetails.getAlertLevelAsString;
+import static org.apache.geode.management.internal.ManagementConstants.AGGREGATE_MBEAN_PATTERN;
+import static org.apache.geode.management.internal.ManagementConstants.ASYNC_EVENT_QUEUE_CLOSED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.ASYNC_EVENT_QUEUE_CREATED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.CACHE_SERVER_STARTED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.CACHE_SERVER_STOPPED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.CACHE_SERVICE_CREATED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.CLIENT_CRASHED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.CLIENT_JOINED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.CLIENT_LEFT_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.DISK_STORE_CLOSED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.DISK_STORE_CREATED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_RECEIVER_CREATED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_RECEIVER_DESTROYED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_RECEIVER_STARTED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_RECEIVER_STOPPED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_SENDER_CREATED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_SENDER_PAUSED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_SENDER_REMOVED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_SENDER_RESUMED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_SENDER_STARTED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.GATEWAY_SENDER_STOPPED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.LOCATOR_STARTED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.LOCK_SERVICE_CLOSED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.LOCK_SERVICE_CREATED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.REGION_CLOSED_PREFIX;
+import static org.apache.geode.management.internal.ManagementConstants.REGION_CREATED_PREFIX;
+
+import java.lang.management.ManagementFactory;
 import java.lang.reflect.Type;
-import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -30,18 +89,16 @@
 import javax.management.ObjectInstance;
 import javax.management.ObjectName;
 
-import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.Logger;
 
 import org.apache.geode.annotations.Immutable;
-import org.apache.geode.annotations.internal.MakeNotStatic;
-import org.apache.geode.cache.Cache;
 import org.apache.geode.cache.DiskStore;
 import org.apache.geode.cache.Region;
 import org.apache.geode.cache.asyncqueue.AsyncEventQueue;
 import org.apache.geode.cache.server.CacheServer;
 import org.apache.geode.cache.wan.GatewayReceiver;
 import org.apache.geode.cache.wan.GatewaySender;
+import org.apache.geode.distributed.DistributedMember;
 import org.apache.geode.distributed.Locator;
 import org.apache.geode.distributed.internal.ClusterDistributionManager;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
@@ -51,7 +108,6 @@
 import org.apache.geode.internal.ClassLoadUtil;
 import org.apache.geode.internal.cache.CacheService;
 import org.apache.geode.internal.cache.InternalCache;
-import org.apache.geode.internal.cache.LocalRegion;
 import org.apache.geode.internal.cache.PartitionedRegionHelper;
 import org.apache.geode.internal.logging.LogService;
 import org.apache.geode.management.AsyncEventQueueMXBean;
@@ -59,8 +115,6 @@
 import org.apache.geode.management.DiskStoreMXBean;
 import org.apache.geode.management.GatewayReceiverMXBean;
 import org.apache.geode.management.GatewaySenderMXBean;
-import org.apache.geode.management.JMXNotificationType;
-import org.apache.geode.management.JMXNotificationUserData;
 import org.apache.geode.management.LocatorMXBean;
 import org.apache.geode.management.LockServiceMXBean;
 import org.apache.geode.management.ManagementException;
@@ -71,7 +125,6 @@
 import org.apache.geode.management.internal.AlertDetails;
 import org.apache.geode.management.internal.FederationComponent;
 import org.apache.geode.management.internal.MBeanJMXAdapter;
-import org.apache.geode.management.internal.ManagementConstants;
 import org.apache.geode.management.internal.SystemManagementService;
 import org.apache.geode.management.membership.ClientMembership;
 import org.apache.geode.management.membership.ClientMembershipEvent;
@@ -83,6 +136,7 @@
  * Acts as an intermediate between MBean layer and Federation Layer. Handles all Call backs from
  * GemFire to instantiate or remove MBeans from GemFire Domain.
  *
+ * <p>
  * Even though this class have a lot of utility functions it interacts with the state of the system
  * and contains some state itself.
  */
@@ -90,95 +144,57 @@
 
   private static final Logger logger = LogService.getLogger();
 
-  /** Internal ManagementService Instance **/
-  private SystemManagementService service;
-
-  /** GemFire Cache impl **/
-  private InternalCache internalCache;
-
-  /** Member Name **/
-  private String memberSource;
-
-  /**
-   * emitter is a helper class for sending notifications on behalf of the MemberMBean
-   **/
-  private NotificationBroadcasterSupport memberLevelNotifEmitter;
-
-  /** The <code>MBeanServer</code> for this application */
-  @MakeNotStatic
-  public static final MBeanServer mbeanServer = MBeanJMXAdapter.mbeanServer;
-
-  /** MemberMBean instance **/
-  private MemberMBean memberBean;
-
-  private volatile boolean serviceInitialised = false;
-
-  @MakeNotStatic
-  private MBeanAggregator aggregator;
-
   @Immutable
-  public static final List<Class> refreshOnInit;
+  private static final List<String> INTERNAL_LOCK_SERVICES =
+      unmodifiableList(asList(DLockService.DTLS, DLockService.LTLS,
+          PartitionedRegionHelper.PARTITION_LOCK_SERVICE_NAME,
+          PeerTypeRegistration.LOCK_SERVICE_NAME));
 
-  @Immutable
-  public static final List<String> internalLocks;
-
-  static {
-    refreshOnInit =
-        Collections.unmodifiableList(Arrays.asList(RegionMXBean.class, MemberMXBean.class));
-
-    internalLocks = Collections.unmodifiableList(Arrays.asList(
-        DLockService.DTLS, // From reserved lock service name
-        DLockService.LTLS, // From reserved lock service name
-        PartitionedRegionHelper.PARTITION_LOCK_SERVICE_NAME,
-        PeerTypeRegistration.LOCK_SERVICE_NAME));
-  }
-
-  protected MemberMBeanBridge memberMBeanBridge;
-
+  private final MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
   private final Object regionOpLock = new Object();
 
+  private SystemManagementService service;
+  private InternalCache internalCache;
+  private String memberSource;
+  private NotificationBroadcasterSupport memberLevelNotificationEmitter;
+  private MemberMBean memberBean;
+  private MBeanAggregator aggregator;
+  private MemberMBeanBridge memberMBeanBridge;
+
+  private volatile boolean serviceInitialised;
+
   /**
-   * Adapter life cycle is tied with the Cache . So its better to make all cache level artifacts as
+   * Adapter life cycle is tied with the Cache. So its better to make all cache level artifacts as
    * instance variable
-   *
-   * @param cache gemfire cache
    */
-  protected void handleCacheCreation(InternalCache cache) throws ManagementException {
+  void handleCacheCreation(InternalCache cache) throws ManagementException {
     try {
-      this.internalCache = cache;
-      this.service =
-          (SystemManagementService) ManagementService.getManagementService(internalCache);
+      internalCache = cache;
+      service = (SystemManagementService) ManagementService.getManagementService(internalCache);
 
-      this.memberMBeanBridge = new MemberMBeanBridge(internalCache, service).init();
-      this.memberBean = new MemberMBean(memberMBeanBridge);
-      this.memberLevelNotifEmitter = memberBean;
+      memberMBeanBridge = new MemberMBeanBridge(internalCache, service).init();
+      memberBean = new MemberMBean(memberMBeanBridge);
+      memberLevelNotificationEmitter = memberBean;
+      memberSource = MBeanJMXAdapter.getMemberNameOrUniqueId(cache.getMyId());
 
-      ObjectName memberMBeanName = MBeanJMXAdapter.getMemberMBeanName(
-          InternalDistributedSystem.getConnectedInstance().getDistributedMember());
+      // Type casting to MemberMXBean to expose only those methods described in interface
+      ObjectName objectName = MBeanJMXAdapter.getMemberMBeanName(cache.getMyId());
+      ObjectName federatedName = service.registerInternalMBean(memberBean, objectName);
+      service.federate(federatedName, MemberMXBean.class, true);
 
-      memberSource = MBeanJMXAdapter
-          .getMemberNameOrUniqueId(internalCache.getDistributedSystem().getDistributedMember());
+      serviceInitialised = true;
 
-      // Type casting to MemberMXBean to expose only those methods described in
-      // the interface;
-      ObjectName changedMBeanName = service.registerInternalMBean(memberBean, memberMBeanName);
-      service.federate(changedMBeanName, MemberMXBean.class, true);
-
-      this.serviceInitialised = true;
-
-      // Service initialised is only for ManagementService and not necessarily
-      // Manager service.
+      // Service initialised is only for ManagementService and not necessarily Manager service.
 
       // For situations where locator is created before any cache is created
       if (InternalLocator.hasLocator()) {
-        Locator loc = InternalLocator.getLocator();
-        handleLocatorStart(loc);
+        handleLocatorStart(InternalLocator.getLocator());
       }
 
       if (cache.getInternalDistributedSystem().getConfig().getJmxManager()) {
-        this.service.createManager();
+        service.createManager();
         if (cache.getInternalDistributedSystem().getConfig().getJmxManagerStart()) {
-          this.service.startManager();
+          service.startManager();
         }
       }
 
@@ -201,48 +217,50 @@
   /**
    * Handles all the distributed mbean creation part when a Manager is started
    */
-  protected void handleManagerStart() throws ManagementException {
+  void handleManagerStart() throws ManagementException {
     if (!isServiceInitialised("handleManagerStart")) {
       return;
     }
-    MBeanJMXAdapter jmxAdapter = service.getJMXAdapter();
-    Map<ObjectName, Object> registeredMBeans = jmxAdapter.getLocalGemFireMBean();
 
-    DistributedSystemBridge dsBridge = new DistributedSystemBridge(service, internalCache);
-    this.aggregator = new MBeanAggregator(dsBridge);
+    DistributedSystemBridge distributedSystemBridge =
+        new DistributedSystemBridge(service, internalCache);
+    aggregator = new MBeanAggregator(distributedSystemBridge);
+
     // register the aggregator for Federation framework to use
     service.addProxyListener(aggregator);
 
-    /*
-     * get the local member mbean as it need to be provided to aggregator first
-     */
+    // get the local member mbean as it need to be provided to aggregator first
+    MemberMXBean localMemberMXBean = service.getMemberMXBean();
 
-    MemberMXBean localMember = service.getMemberMXBean();
     ObjectName memberObjectName = MBeanJMXAdapter.getMemberMBeanName(
         InternalDistributedSystem.getConnectedInstance().getDistributedMember());
 
-    FederationComponent addedComp =
+    FederationComponent memberFederation =
         service.getLocalManager().getFedComponents().get(memberObjectName);
 
-    service.afterCreateProxy(memberObjectName, MemberMXBean.class, localMember, addedComp);
+    service.afterCreateProxy(memberObjectName, MemberMXBean.class, localMemberMXBean,
+        memberFederation);
+
+    MBeanJMXAdapter jmxAdapter = service.getJMXAdapter();
+    Map<ObjectName, Object> registeredMBeans = jmxAdapter.getLocalGemFireMBean();
 
     for (ObjectName objectName : registeredMBeans.keySet()) {
       if (objectName.equals(memberObjectName)) {
         continue;
       }
       Object object = registeredMBeans.get(objectName);
-      ObjectInstance instance;
       try {
-        instance = mbeanServer.getObjectInstance(objectName);
+        ObjectInstance instance = mbeanServer.getObjectInstance(objectName);
         String className = instance.getClassName();
-        Class cls = ClassLoadUtil.classFromName(className);
-        Type[] intfTyps = cls.getGenericInterfaces();
+        Class clazz = ClassLoadUtil.classFromName(className);
+        Type[] interfaceTypes = clazz.getGenericInterfaces();
 
-        FederationComponent newObj = service.getLocalManager().getFedComponents().get(objectName);
+        FederationComponent federation =
+            service.getLocalManager().getFedComponents().get(objectName);
 
-        for (Type intfTyp1 : intfTyps) {
-          Class intfTyp = (Class) intfTyp1;
-          service.afterCreateProxy(objectName, intfTyp, object, newObj);
+        for (Type interfaceType : interfaceTypes) {
+          Class interfaceTypeAsClass = (Class) interfaceType;
+          service.afterCreateProxy(objectName, interfaceTypeAsClass, object, federation);
 
         }
       } catch (InstanceNotFoundException e) {
@@ -263,75 +281,69 @@
    * Handles all the clean up activities when a Manager is stopped It clears the distributed mbeans
    * and underlying data structures
    */
-  protected void handleManagerStop() throws ManagementException {
+  void handleManagerStop() throws ManagementException {
     if (!isServiceInitialised("handleManagerStop")) {
       return;
     }
-    MBeanJMXAdapter jmxAdapter = service.getJMXAdapter();
-    Map<ObjectName, Object> registeredMBeans = jmxAdapter.getLocalGemFireMBean();
 
-    ObjectName aggregatemMBeanPattern;
-    try {
-      aggregatemMBeanPattern = new ObjectName(ManagementConstants.AGGREGATE_MBEAN_PATTERN);
-    } catch (MalformedObjectNameException | NullPointerException e1) {
-      throw new ManagementException(e1);
-    }
-
-    MemberMXBean localMember = service.getMemberMXBean();
+    MemberMXBean localMemberMXBean = service.getMemberMXBean();
 
     ObjectName memberObjectName = MBeanJMXAdapter.getMemberMBeanName(
         InternalDistributedSystem.getConnectedInstance().getDistributedMember());
 
-    FederationComponent removedComp =
+    FederationComponent memberFederation =
         service.getLocalManager().getFedComponents().get(memberObjectName);
 
-    service.afterRemoveProxy(memberObjectName, MemberMXBean.class, localMember, removedComp);
+    service.afterRemoveProxy(memberObjectName, MemberMXBean.class, localMemberMXBean,
+        memberFederation);
 
+    ObjectName aggregateMBeanPattern = aggregateMBeanPattern();
+    MBeanJMXAdapter jmxAdapter = service.getJMXAdapter();
+    Map<ObjectName, Object> registeredMBeans = jmxAdapter.getLocalGemFireMBean();
     for (ObjectName objectName : registeredMBeans.keySet()) {
       if (objectName.equals(memberObjectName)) {
         continue;
       }
-      if (aggregatemMBeanPattern.apply(objectName)) {
+      if (aggregateMBeanPattern.apply(objectName)) {
         continue;
       }
       Object object = registeredMBeans.get(objectName);
-      ObjectInstance instance;
       try {
-        instance = mbeanServer.getObjectInstance(objectName);
+        ObjectInstance instance = mbeanServer.getObjectInstance(objectName);
         String className = instance.getClassName();
-        Class cls = ClassLoadUtil.classFromName(className);
-        Type[] intfTyps = cls.getGenericInterfaces();
+        Class clazz = ClassLoadUtil.classFromName(className);
+        Type[] interfaceTypes = clazz.getGenericInterfaces();
 
-        FederationComponent oldObj = service.getLocalManager().getFedComponents().get(objectName);
+        FederationComponent federation =
+            service.getLocalManager().getFedComponents().get(objectName);
 
-        for (Type intfTyp1 : intfTyps) {
-          Class intfTyp = (Class) intfTyp1;
-          service.afterRemoveProxy(objectName, intfTyp, object, oldObj);
+        for (Type interfaceType : interfaceTypes) {
+          Class interfaceTypeClass = (Class) interfaceType;
+          service.afterRemoveProxy(objectName, interfaceTypeClass, object, federation);
         }
       } catch (InstanceNotFoundException | ClassNotFoundException e) {
         logger.warn("Failed to invoke aggregator for {} with exception {}", objectName,
             e.getMessage(), e);
       }
     }
-    service.removeProxyListener(this.aggregator);
-    this.aggregator = null;
+
+    service.removeProxyListener(aggregator);
+    aggregator = null;
   }
 
   /**
    * Assumption is always cache and MemberMbean has been will be created first
    */
-  protected void handleManagerCreation() throws ManagementException {
+  void handleManagerCreation() throws ManagementException {
     if (!isServiceInitialised("handleManagerCreation")) {
       return;
     }
 
-    ObjectName managerMBeanName = MBeanJMXAdapter.getManagerName();
+    ObjectName objectName = MBeanJMXAdapter.getManagerName();
+    ManagerMBeanBridge managerMBeanBridge = new ManagerMBeanBridge(service);
+    ManagerMXBean managerMXBean = new ManagerMBean(managerMBeanBridge);
 
-    ManagerMBeanBridge bridge = new ManagerMBeanBridge(service);
-
-    ManagerMXBean bean = new ManagerMBean(bridge);
-
-    service.registerInternalMBean(bean, managerMBeanName);
+    service.registerInternalMBean(managerMXBean, objectName);
   }
 
   /**
@@ -340,87 +352,85 @@
    *
    * @param region the region for which the call back is invoked
    */
-  public <K, V> void handleRegionCreation(Region<K, V> region) throws ManagementException {
+  <K, V> void handleRegionCreation(Region<K, V> region) throws ManagementException {
     if (!isServiceInitialised("handleRegionCreation")) {
       return;
     }
+
     // Moving region creation operation inside a guarded block
     // After getting access to regionOpLock it again checks for region
     // destroy status
 
     synchronized (regionOpLock) {
-      LocalRegion localRegion = (LocalRegion) region;
-      if (localRegion.isDestroyed()) {
+      if (region.isDestroyed()) {
         return;
       }
+
       // Bridge is responsible for extracting data from GemFire Layer
-      RegionMBeanBridge<K, V> bridge = RegionMBeanBridge.getInstance(region);
-
-      RegionMXBean regionMBean = new RegionMBean<>(bridge);
-      ObjectName regionMBeanName = MBeanJMXAdapter.getRegionMBeanName(
+      RegionMBeanBridge<K, V> regionMBeanBridge = RegionMBeanBridge.getInstance(region);
+      RegionMXBean regionMXBean = new RegionMBean<>(regionMBeanBridge);
+      ObjectName objectName = MBeanJMXAdapter.getRegionMBeanName(
           internalCache.getDistributedSystem().getDistributedMember(), region.getFullPath());
-      ObjectName changedMBeanName = service.registerInternalMBean(regionMBean, regionMBeanName);
-      service.federate(changedMBeanName, RegionMXBean.class, true);
+      ObjectName federatedName = service.registerInternalMBean(regionMXBean, objectName);
+      service.federate(federatedName, RegionMXBean.class, true);
 
-      Notification notification = new Notification(JMXNotificationType.REGION_CREATED, memberSource,
+      Notification notification = new Notification(REGION_CREATED, memberSource,
           SequenceNumber.next(), System.currentTimeMillis(),
-          ManagementConstants.REGION_CREATED_PREFIX + region.getFullPath());
-      memberLevelNotifEmitter.sendNotification(notification);
+          REGION_CREATED_PREFIX + region.getFullPath());
+      memberLevelNotificationEmitter.sendNotification(notification);
+
       memberMBeanBridge.addRegion(region);
     }
   }
 
   /**
    * Handles Disk Creation. Will create DiskStoreMXBean and will send a notification
-   *
-   * @param disk the disk store for which the call back is invoked
    */
-  protected void handleDiskCreation(DiskStore disk) throws ManagementException {
+  void handleDiskCreation(DiskStore diskStore) throws ManagementException {
     if (!isServiceInitialised("handleDiskCreation")) {
       return;
     }
-    DiskStoreMBeanBridge bridge = new DiskStoreMBeanBridge(disk);
-    DiskStoreMXBean diskStoreMBean = new DiskStoreMBean(bridge);
-    ObjectName diskStoreMBeanName = MBeanJMXAdapter.getDiskStoreMBeanName(
-        internalCache.getDistributedSystem().getDistributedMember(), disk.getName());
-    ObjectName changedMBeanName = service.registerInternalMBean(diskStoreMBean, diskStoreMBeanName);
 
-    service.federate(changedMBeanName, DiskStoreMXBean.class, true);
+    DiskStoreMBeanBridge diskStoreMBeanBridge = new DiskStoreMBeanBridge(diskStore);
+    DiskStoreMXBean diskStoreMXBean = new DiskStoreMBean(diskStoreMBeanBridge);
+    ObjectName objectName = MBeanJMXAdapter.getDiskStoreMBeanName(
+        internalCache.getDistributedSystem().getDistributedMember(), diskStore.getName());
+    ObjectName federatedName = service.registerInternalMBean(diskStoreMXBean, objectName);
+    service.federate(federatedName, DiskStoreMXBean.class, true);
 
-    Notification notification = new Notification(JMXNotificationType.DISK_STORE_CREATED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.DISK_STORE_CREATED_PREFIX + disk.getName());
-    memberLevelNotifEmitter.sendNotification(notification);
-    memberMBeanBridge.addDiskStore(disk);
+    Notification notification = new Notification(DISK_STORE_CREATED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        DISK_STORE_CREATED_PREFIX + diskStore.getName());
+    memberLevelNotificationEmitter.sendNotification(notification);
+
+    memberMBeanBridge.addDiskStore(diskStore);
   }
 
   /**
    * Handles LockService Creation
    *
    */
-  protected void handleLockServiceCreation(DLockService lockService) throws ManagementException {
+  void handleLockServiceCreation(DLockService lockService) throws ManagementException {
     if (!isServiceInitialised("handleLockServiceCreation")) {
       return;
     }
     // Internal Locks Should not be exposed to client for monitoring
-    if (internalLocks.contains(lockService.getName())) {
+    if (INTERNAL_LOCK_SERVICES.contains(lockService.getName())) {
       return;
     }
-    LockServiceMBeanBridge bridge = new LockServiceMBeanBridge(lockService);
-    LockServiceMXBean lockServiceMBean = new LockServiceMBean(bridge);
 
-    ObjectName lockServiceMBeanName = MBeanJMXAdapter.getLockServiceMBeanName(
+    LockServiceMBeanBridge lockServiceMBeanBridge = new LockServiceMBeanBridge(lockService);
+    LockServiceMXBean lockServiceMXBean = new LockServiceMBean(lockServiceMBeanBridge);
+    ObjectName objectName = MBeanJMXAdapter.getLockServiceMBeanName(
         internalCache.getDistributedSystem().getDistributedMember(), lockService.getName());
+    ObjectName federatedName =
+        service.registerInternalMBean(lockServiceMXBean, objectName);
+    service.federate(federatedName, LockServiceMXBean.class, true);
 
-    ObjectName changedMBeanName =
-        service.registerInternalMBean(lockServiceMBean, lockServiceMBeanName);
-
-    service.federate(changedMBeanName, LockServiceMXBean.class, true);
-
-    Notification notification = new Notification(JMXNotificationType.LOCK_SERVICE_CREATED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.LOCK_SERVICE_CREATED_PREFIX + lockService.getName());
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(LOCK_SERVICE_CREATED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        LOCK_SERVICE_CREATED_PREFIX + lockService.getName());
+    memberLevelNotificationEmitter.sendNotification(notification);
 
     memberMBeanBridge.addLockServiceStats(lockService);
   }
@@ -430,165 +440,151 @@
    *
    * @param sender the specific gateway sender
    */
-  protected void handleGatewaySenderCreation(GatewaySender sender) throws ManagementException {
+  void handleGatewaySenderCreation(GatewaySender sender) throws ManagementException {
     if (!isServiceInitialised("handleGatewaySenderCreation")) {
       return;
     }
-    GatewaySenderMBeanBridge bridge = new GatewaySenderMBeanBridge(sender);
 
-    GatewaySenderMXBean senderMBean = new GatewaySenderMBean(bridge);
-    ObjectName senderObjectName = MBeanJMXAdapter.getGatewaySenderMBeanName(
+    GatewaySenderMBeanBridge gatewaySenderMBeanBridge = new GatewaySenderMBeanBridge(sender);
+    GatewaySenderMXBean gatewaySenderMXBean = new GatewaySenderMBean(gatewaySenderMBeanBridge);
+    ObjectName objectName = MBeanJMXAdapter.getGatewaySenderMBeanName(
         internalCache.getDistributedSystem().getDistributedMember(), sender.getId());
+    ObjectName federatedName = service.registerInternalMBean(gatewaySenderMXBean, objectName);
+    service.federate(federatedName, GatewaySenderMXBean.class, true);
 
-    ObjectName changedMBeanName = service.registerInternalMBean(senderMBean, senderObjectName);
-
-    service.federate(changedMBeanName, GatewaySenderMXBean.class, true);
-
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_SENDER_CREATED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_SENDER_CREATED_PREFIX);
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_SENDER_CREATED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), GATEWAY_SENDER_CREATED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
   /**
    * Handles Gateway receiver creation
    *
-   * @param recv specific gateway receiver
+   * @param gatewayReceiver specific gateway receiver
    */
-  protected void handleGatewayReceiverCreate(GatewayReceiver recv) throws ManagementException {
+  void handleGatewayReceiverCreate(GatewayReceiver gatewayReceiver) throws ManagementException {
     if (!isServiceInitialised("handleGatewayReceiverCreate")) {
       return;
     }
-    if (!recv.isManualStart()) {
+    if (!gatewayReceiver.isManualStart()) {
       return;
     }
 
-    createGatewayReceiverMBean(recv);
+    createGatewayReceiverMBean(gatewayReceiver);
   }
 
-  private void createGatewayReceiverMBean(GatewayReceiver recv) {
-    GatewayReceiverMBeanBridge bridge = new GatewayReceiverMBeanBridge(recv);
-
-    GatewayReceiverMXBean receiverMBean = new GatewayReceiverMBean(bridge);
-    ObjectName recvObjectName = MBeanJMXAdapter
+  private void createGatewayReceiverMBean(GatewayReceiver gatewayReceiver) {
+    GatewayReceiverMBeanBridge gatewayReceiverMBeanBridge =
+        new GatewayReceiverMBeanBridge(gatewayReceiver);
+    GatewayReceiverMXBean gatewayReceiverMXBean =
+        new GatewayReceiverMBean(gatewayReceiverMBeanBridge);
+    ObjectName objectName = MBeanJMXAdapter
         .getGatewayReceiverMBeanName(internalCache.getDistributedSystem().getDistributedMember());
+    ObjectName federatedName = service.registerInternalMBean(gatewayReceiverMXBean, objectName);
+    service.federate(federatedName, GatewayReceiverMXBean.class, true);
 
-    ObjectName changedMBeanName = service.registerInternalMBean(receiverMBean, recvObjectName);
-
-    service.federate(changedMBeanName, GatewayReceiverMXBean.class, true);
-
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_RECEIVER_CREATED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_RECEIVER_CREATED_PREFIX);
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_RECEIVER_CREATED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), GATEWAY_RECEIVER_CREATED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  /**
-   * Handles Gateway receiver destroy
-   *
-   * @param recv specific gateway receiver
-   */
-  protected void handleGatewayReceiverDestroy(GatewayReceiver recv) throws ManagementException {
+  void handleGatewayReceiverDestroy() throws ManagementException {
     if (!isServiceInitialised("handleGatewayReceiverDestroy")) {
       return;
     }
 
-    GatewayReceiverMBean mbean = (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
-    GatewayReceiverMBeanBridge bridge = mbean.getBridge();
+    GatewayReceiverMBean gatewayReceiverMBean =
+        (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
+    GatewayReceiverMBeanBridge gatewayReceiverMBeanBridge = gatewayReceiverMBean.getBridge();
 
-    bridge.destroyServer();
-    ObjectName objectName = (MBeanJMXAdapter
-        .getGatewayReceiverMBeanName(internalCache.getDistributedSystem().getDistributedMember()));
+    gatewayReceiverMBeanBridge.destroyServer();
 
+    ObjectName objectName = MBeanJMXAdapter
+        .getGatewayReceiverMBeanName(internalCache.getDistributedSystem().getDistributedMember());
     service.unregisterMBean(objectName);
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_RECEIVER_DESTROYED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_RECEIVER_DESTROYED_PREFIX);
-    memberLevelNotifEmitter.sendNotification(notification);
+
+    Notification notification = new Notification(GATEWAY_RECEIVER_DESTROYED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), GATEWAY_RECEIVER_DESTROYED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
   /**
    * Handles Gateway receiver creation
    *
-   * @param recv specific gateway receiver
+   * @param gatewayReceiver specific gateway receiver
    */
-  protected void handleGatewayReceiverStart(GatewayReceiver recv) throws ManagementException {
+  void handleGatewayReceiverStart(GatewayReceiver gatewayReceiver) throws ManagementException {
     if (!isServiceInitialised("handleGatewayReceiverStart")) {
       return;
     }
 
-    if (!recv.isManualStart()) {
-      createGatewayReceiverMBean(recv);
+    if (!gatewayReceiver.isManualStart()) {
+      createGatewayReceiverMBean(gatewayReceiver);
     }
 
-    GatewayReceiverMBean mbean = (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
-    GatewayReceiverMBeanBridge bridge = mbean.getBridge();
+    GatewayReceiverMBean gatewayReceiverMBean =
+        (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
+    GatewayReceiverMBeanBridge gatewayReceiverMBeanBridge = gatewayReceiverMBean.getBridge();
 
-    bridge.startServer();
+    gatewayReceiverMBeanBridge.startServer();
 
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_RECEIVER_STARTED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_RECEIVER_STARTED_PREFIX);
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_RECEIVER_STARTED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), GATEWAY_RECEIVER_STARTED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  /**
-   * Handles Gateway receiver creation
-   *
-   * @param recv specific gateway receiver
-   */
-  protected void handleGatewayReceiverStop(GatewayReceiver recv) throws ManagementException {
+  void handleGatewayReceiverStop() throws ManagementException {
     if (!isServiceInitialised("handleGatewayReceiverStop")) {
       return;
     }
-    GatewayReceiverMBean mbean = (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
-    GatewayReceiverMBeanBridge bridge = mbean.getBridge();
 
-    bridge.stopServer();
+    GatewayReceiverMBean gatewayReceiverMBean =
+        (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
+    GatewayReceiverMBeanBridge gatewayReceiverMBeanBridge = gatewayReceiverMBean.getBridge();
 
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_RECEIVER_STOPPED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_RECEIVER_STOPPED_PREFIX);
-    memberLevelNotifEmitter.sendNotification(notification);
+    gatewayReceiverMBeanBridge.stopServer();
+
+    Notification notification = new Notification(GATEWAY_RECEIVER_STOPPED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), GATEWAY_RECEIVER_STOPPED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  protected void handleAsyncEventQueueCreation(AsyncEventQueue queue) throws ManagementException {
+  void handleAsyncEventQueueCreation(AsyncEventQueue asyncEventQueue) throws ManagementException {
     if (!isServiceInitialised("handleAsyncEventQueueCreation")) {
       return;
     }
-    AsyncEventQueueMBeanBridge bridge = new AsyncEventQueueMBeanBridge(queue);
-    AsyncEventQueueMXBean queueMBean = new AsyncEventQueueMBean(bridge);
-    ObjectName senderObjectName = MBeanJMXAdapter.getAsyncEventQueueMBeanName(
-        internalCache.getDistributedSystem().getDistributedMember(), queue.getId());
 
-    ObjectName changedMBeanName = service.registerInternalMBean(queueMBean, senderObjectName);
+    AsyncEventQueueMBeanBridge asyncEventQueueMBeanBridge =
+        new AsyncEventQueueMBeanBridge(asyncEventQueue);
+    AsyncEventQueueMXBean asyncEventQueueMXBean =
+        new AsyncEventQueueMBean(asyncEventQueueMBeanBridge);
+    ObjectName objectName = MBeanJMXAdapter.getAsyncEventQueueMBeanName(
+        internalCache.getDistributedSystem().getDistributedMember(), asyncEventQueue.getId());
+    ObjectName federatedName = service.registerInternalMBean(asyncEventQueueMXBean, objectName);
+    service.federate(federatedName, AsyncEventQueueMXBean.class, true);
 
-    service.federate(changedMBeanName, AsyncEventQueueMXBean.class, true);
-
-    Notification notification = new Notification(JMXNotificationType.ASYNC_EVENT_QUEUE_CREATED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.ASYNC_EVENT_QUEUE_CREATED_PREFIX);
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(ASYNC_EVENT_QUEUE_CREATED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), ASYNC_EVENT_QUEUE_CREATED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  /**
-   * Handles AsyncEventQueue Removal
-   *
-   * @param queue The AsyncEventQueue being removed
-   */
-  protected void handleAsyncEventQueueRemoval(AsyncEventQueue queue) throws ManagementException {
+  void handleAsyncEventQueueRemoval(AsyncEventQueue asyncEventQueue) throws ManagementException {
     if (!isServiceInitialised("handleAsyncEventQueueRemoval")) {
       return;
     }
 
-    ObjectName asycnEventQueueMBeanName = MBeanJMXAdapter.getAsyncEventQueueMBeanName(
-        internalCache.getDistributedSystem().getDistributedMember(), queue.getId());
-    AsyncEventQueueMBean bean;
+    ObjectName objectName = MBeanJMXAdapter.getAsyncEventQueueMBeanName(
+        internalCache.getDistributedSystem().getDistributedMember(), asyncEventQueue.getId());
+
     try {
-      bean = (AsyncEventQueueMBean) service.getLocalAsyncEventQueueMXBean(queue.getId());
-      if (bean == null) {
+      AsyncEventQueueMBean asyncEventQueueMBean =
+          (AsyncEventQueueMBean) service.getLocalAsyncEventQueueMXBean(asyncEventQueue.getId());
+      if (asyncEventQueueMBean == null) {
         return;
       }
+
+      asyncEventQueueMBean.stopMonitor();
+
     } catch (ManagementException e) {
       // If no bean found its a NO-OP
       if (logger.isDebugEnabled()) {
@@ -597,55 +593,39 @@
       return;
     }
 
-    bean.stopMonitor();
+    service.unregisterMBean(objectName);
 
-    service.unregisterMBean(asycnEventQueueMBeanName);
-
-    Notification notification = new Notification(JMXNotificationType.ASYNC_EVENT_QUEUE_CLOSED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.ASYNC_EVENT_QUEUE_CLOSED_PREFIX + queue.getId());
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(ASYNC_EVENT_QUEUE_CLOSED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        ASYNC_EVENT_QUEUE_CLOSED_PREFIX + asyncEventQueue.getId());
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
   /**
    * Sends the alert with the Object source as member. This notification will get filtered out for
    * particular alert level
-   *
    */
-  protected void handleSystemNotification(AlertDetails details) {
+  void handleSystemNotification(AlertDetails alertDetails) {
     if (!isServiceInitialised("handleSystemNotification")) {
       return;
     }
+
     if (service.isManager()) {
       String systemSource = "DistributedSystem("
           + service.getDistributedSystemMXBean().getDistributedSystemId() + ")";
-      Map<String, String> userData = prepareUserData(details);
-
-
-      Notification notification = new Notification(JMXNotificationType.SYSTEM_ALERT, systemSource,
-          SequenceNumber.next(), details.getMsgTime().getTime(), details.getMsg());
-
-      notification.setUserData(userData);
+      Notification notification = new Notification(SYSTEM_ALERT, systemSource,
+          SequenceNumber.next(), alertDetails.getMsgTime().getTime(), alertDetails.getMsg());
+      notification.setUserData(prepareUserData(alertDetails));
       service.handleNotification(notification);
     }
   }
 
-  private Map<String, String> prepareUserData(AlertDetails details) {
+  private Map<String, String> prepareUserData(AlertDetails alertDetails) {
     Map<String, String> userData = new HashMap<>();
-    userData.put(JMXNotificationUserData.ALERT_LEVEL,
-        AlertDetails.getAlertLevelAsString(details.getAlertLevel()));
 
-    String source = details.getSource();
-    userData.put(JMXNotificationUserData.THREAD, source);
-
-    InternalDistributedMember sender = details.getSender();
-    String nameOrId = memberSource;
-    if (sender != null) {
-      nameOrId = sender.getName();
-      nameOrId = StringUtils.isNotBlank(nameOrId) ? nameOrId : sender.getId();
-    }
-
-    userData.put(JMXNotificationUserData.MEMBER, nameOrId);
+    userData.put(ALERT_LEVEL, getAlertLevelAsString(alertDetails.getAlertLevel()));
+    userData.put(THREAD, alertDetails.getSource());
+    userData.put(MEMBER, getNameOrId(alertDetails.getSender()));
 
     return userData;
   }
@@ -655,83 +635,68 @@
    *
    * @param cacheServer cache server instance
    */
-  protected void handleCacheServerStart(CacheServer cacheServer) {
+  void handleCacheServerStart(CacheServer cacheServer) {
     if (!isServiceInitialised("handleCacheServerStart")) {
       return;
     }
 
     CacheServerBridge cacheServerBridge = new CacheServerBridge(internalCache, cacheServer);
     cacheServerBridge.setMemberMBeanBridge(memberMBeanBridge);
-
     CacheServerMBean cacheServerMBean = new CacheServerMBean(cacheServerBridge);
-
-    ObjectName cacheServerMBeanName = MBeanJMXAdapter.getClientServiceMBeanName(
+    ObjectName objectName = MBeanJMXAdapter.getClientServiceMBeanName(
         cacheServer.getPort(), internalCache.getDistributedSystem().getDistributedMember());
-
-    ObjectName changedMBeanName =
-        service.registerInternalMBean(cacheServerMBean, cacheServerMBeanName);
+    ObjectName federatedName = service.registerInternalMBean(cacheServerMBean, objectName);
 
     ClientMembershipListener managementClientListener = new CacheServerMembershipListenerAdapter(
-        cacheServerMBean, memberLevelNotifEmitter, changedMBeanName);
+        cacheServerMBean, memberLevelNotificationEmitter, federatedName);
     ClientMembership.registerClientMembershipListener(managementClientListener);
-
     cacheServerBridge.setClientMembershipListener(managementClientListener);
 
-    service.federate(changedMBeanName, CacheServerMXBean.class, true);
+    service.federate(federatedName, CacheServerMXBean.class, true);
 
-    Notification notification = new Notification(JMXNotificationType.CACHE_SERVER_STARTED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.CACHE_SERVER_STARTED_PREFIX);
-
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(CACHE_SERVER_STARTED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), CACHE_SERVER_STARTED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
 
     memberMBeanBridge.setCacheServer(true);
   }
 
   /**
    * Assumption is its a cache server instance. For Gateway receiver there will be a separate method
-   *
-   * @param server cache server instance
    */
-  protected void handleCacheServerStop(CacheServer server) {
+  void handleCacheServerStop(CacheServer server) {
     if (!isServiceInitialised("handleCacheServerStop")) {
       return;
     }
 
-    CacheServerMBean mbean = (CacheServerMBean) service.getLocalCacheServerMXBean(server.getPort());
+    CacheServerMBean cacheServerMBean =
+        (CacheServerMBean) service.getLocalCacheServerMXBean(server.getPort());
 
-    ClientMembershipListener listener = mbean.getBridge().getClientMembershipListener();
-
-    if (listener != null) {
-      ClientMembership.unregisterClientMembershipListener(listener);
+    ClientMembershipListener clientMembershipListener =
+        cacheServerMBean.getBridge().getClientMembershipListener();
+    if (clientMembershipListener != null) {
+      ClientMembership.unregisterClientMembershipListener(clientMembershipListener);
     }
 
-    mbean.stopMonitor();
+    cacheServerMBean.stopMonitor();
 
-    ObjectName cacheServerMBeanName = MBeanJMXAdapter.getClientServiceMBeanName(server.getPort(),
+    ObjectName objectName = MBeanJMXAdapter.getClientServiceMBeanName(server.getPort(),
         internalCache.getDistributedSystem().getDistributedMember());
-    service.unregisterMBean(cacheServerMBeanName);
+    service.unregisterMBean(objectName);
 
-    Notification notification = new Notification(JMXNotificationType.CACHE_SERVER_STOPPED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.CACHE_SERVER_STOPPED_PREFIX);
-
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(CACHE_SERVER_STOPPED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), CACHE_SERVER_STOPPED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
 
     memberMBeanBridge.setCacheServer(false);
   }
 
-  /**
-   * Handles Cache removal. It will automatically remove all MBeans from GemFire Domain
-   *
-   * @param cache GemFire Cache instance. For now client cache is not supported
-   */
-  protected void handleCacheRemoval(Cache cache) throws ManagementException {
+  void handleCacheRemoval() throws ManagementException {
     if (!isServiceInitialised("handleCacheRemoval")) {
       return;
     }
 
-    this.serviceInitialised = false;
+    serviceInitialised = false;
     try {
       cleanUpMonitors();
       cleanBridgeResources();
@@ -746,48 +711,57 @@
     } catch (Exception e) {
       logger.warn(e.getMessage(), e);
     } finally {
-      this.internalCache = null;
-      this.service = null;
-      this.memberMBeanBridge = null;
-      this.memberBean = null;
-      this.memberLevelNotifEmitter = null;
+      internalCache = null;
+      service = null;
+      memberMBeanBridge = null;
+      memberBean = null;
+      memberLevelNotificationEmitter = null;
     }
   }
 
+  private String getNameOrId(DistributedMember member) {
+    if (member == null) {
+      return memberSource;
+    }
+    return isNotBlank(member.getName()) ? member.getName() : member.getId();
+  }
+
   private void cleanUpMonitors() {
-    MemberMBean bean = (MemberMBean) service.getMemberMXBean();
-    if (bean != null) {
-      bean.stopMonitor();
+    MemberMBean memberMBean = (MemberMBean) service.getMemberMXBean();
+    if (memberMBean != null) {
+      memberMBean.stopMonitor();
     }
 
-    Set<GatewaySender> senders = internalCache.getGatewaySenders();
+    Set<GatewaySender> gatewaySenders = internalCache.getGatewaySenders();
 
-    if (senders != null && senders.size() > 0) {
-      for (GatewaySender sender : senders) {
-        GatewaySenderMBean senderMBean =
-            (GatewaySenderMBean) service.getLocalGatewaySenderMXBean(sender.getId());
-        if (senderMBean != null) {
-          senderMBean.stopMonitor();
+    if (gatewaySenders != null && !gatewaySenders.isEmpty()) {
+      for (GatewaySender gatewaySender : gatewaySenders) {
+        GatewaySenderMBean gatewaySenderMBean =
+            (GatewaySenderMBean) service.getLocalGatewaySenderMXBean(gatewaySender.getId());
+        if (gatewaySenderMBean != null) {
+          gatewaySenderMBean.stopMonitor();
         }
       }
     }
 
-    GatewayReceiverMBean receiver = (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
-    if (receiver != null) {
-      receiver.stopMonitor();
+    GatewayReceiverMBean gatewayReceiverMBean =
+        (GatewayReceiverMBean) service.getLocalGatewayReceiverMXBean();
+    if (gatewayReceiverMBean != null) {
+      gatewayReceiverMBean.stopMonitor();
     }
   }
 
   private void cleanBridgeResources() {
-    List<CacheServer> servers = internalCache.getCacheServers();
+    List<CacheServer> cacheServers = internalCache.getCacheServers();
 
-    if (servers != null && servers.size() > 0) {
-      for (CacheServer server : servers) {
-        CacheServerMBean mbean =
-            (CacheServerMBean) service.getLocalCacheServerMXBean(server.getPort());
+    if (cacheServers != null && !cacheServers.isEmpty()) {
+      for (CacheServer cacheServer : cacheServers) {
+        CacheServerMBean cacheServerMBean =
+            (CacheServerMBean) service.getLocalCacheServerMXBean(cacheServer.getPort());
 
-        if (mbean != null) {
-          ClientMembershipListener listener = mbean.getBridge().getClientMembershipListener();
+        if (cacheServerMBean != null) {
+          ClientMembershipListener listener =
+              cacheServerMBean.getBridge().getClientMembershipListener();
 
           if (listener != null) {
             ClientMembership.unregisterClientMembershipListener(listener);
@@ -799,23 +773,24 @@
 
   /**
    * Handles particular region destroy or close operation it will remove the corresponding MBean
-   *
    */
-  protected void handleRegionRemoval(Region region) throws ManagementException {
+  void handleRegionRemoval(Region region) throws ManagementException {
     if (!isServiceInitialised("handleRegionRemoval")) {
       return;
     }
-    /*
-     * Moved region remove operation to a guarded block. If a region is getting created it wont
-     * allow it to destroy any region.
-     */
+
+    // Moved region remove operation to a guarded block. If a region is getting created it won't
+    // allow it to destroy any region.
 
     synchronized (regionOpLock) {
-      ObjectName regionMBeanName = MBeanJMXAdapter.getRegionMBeanName(
+      ObjectName objectName = MBeanJMXAdapter.getRegionMBeanName(
           internalCache.getDistributedSystem().getDistributedMember(), region.getFullPath());
-      RegionMBean bean;
+
       try {
-        bean = (RegionMBean) service.getLocalRegionMBean(region.getFullPath());
+        RegionMBean regionMBean = (RegionMBean) service.getLocalRegionMBean(region.getFullPath());
+        if (regionMBean != null) {
+          regionMBean.stopMonitor();
+        }
       } catch (ManagementException e) {
         // If no bean found its a NO-OP
         // Mostly for situation like DiskAccessException while creating region
@@ -826,37 +801,32 @@
         return;
       }
 
-      if (bean != null) {
-        bean.stopMonitor();
-      }
-      service.unregisterMBean(regionMBeanName);
+      service.unregisterMBean(objectName);
 
-      Notification notification = new Notification(JMXNotificationType.REGION_CLOSED, memberSource,
+      Notification notification = new Notification(REGION_CLOSED, memberSource,
           SequenceNumber.next(), System.currentTimeMillis(),
-          ManagementConstants.REGION_CLOSED_PREFIX + region.getFullPath());
-      memberLevelNotifEmitter.sendNotification(notification);
+          REGION_CLOSED_PREFIX + region.getFullPath());
+      memberLevelNotificationEmitter.sendNotification(notification);
+
       memberMBeanBridge.removeRegion(region);
     }
   }
 
-  /**
-   * Handles DiskStore Removal
-   *
-   */
-  protected void handleDiskRemoval(DiskStore disk) throws ManagementException {
+  void handleDiskRemoval(DiskStore diskStore) throws ManagementException {
     if (!isServiceInitialised("handleDiskRemoval")) {
       return;
     }
 
-    ObjectName diskStoreMBeanName = MBeanJMXAdapter.getDiskStoreMBeanName(
-        internalCache.getDistributedSystem().getDistributedMember(), disk.getName());
+    ObjectName objectName = MBeanJMXAdapter.getDiskStoreMBeanName(
+        internalCache.getDistributedSystem().getDistributedMember(), diskStore.getName());
 
-    DiskStoreMBean bean;
     try {
-      bean = (DiskStoreMBean) service.getLocalDiskStoreMBean(disk.getName());
-      if (bean == null) {
+      DiskStoreMBean diskStoreMBean =
+          (DiskStoreMBean) service.getLocalDiskStoreMBean(diskStore.getName());
+      if (diskStoreMBean == null) {
         return;
       }
+      diskStoreMBean.stopMonitor();
     } catch (ManagementException e) {
       // If no bean found its a NO-OP
       if (logger.isDebugEnabled()) {
@@ -865,192 +835,193 @@
       return;
     }
 
-    bean.stopMonitor();
+    service.unregisterMBean(objectName);
 
-    service.unregisterMBean(diskStoreMBeanName);
+    Notification notification = new Notification(DISK_STORE_CLOSED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        DISK_STORE_CLOSED_PREFIX + diskStore.getName());
+    memberLevelNotificationEmitter.sendNotification(notification);
 
-    Notification notification = new Notification(JMXNotificationType.DISK_STORE_CLOSED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.DISK_STORE_CLOSED_PREFIX + disk.getName());
-    memberLevelNotifEmitter.sendNotification(notification);
-    memberMBeanBridge.removeDiskStore(disk);
+    memberMBeanBridge.removeDiskStore(diskStore);
   }
 
-  /**
-   * Handles Lock Service Removal
-   *
-   * @param lockService lock service instance
-   */
-  protected void handleLockServiceRemoval(DLockService lockService) throws ManagementException {
+  void handleLockServiceRemoval(DLockService lockService) throws ManagementException {
     if (!isServiceInitialised("handleLockServiceRemoval")) {
       return;
     }
 
-    ObjectName lockServiceMBeanName = MBeanJMXAdapter.getLockServiceMBeanName(
+    ObjectName objectName = MBeanJMXAdapter.getLockServiceMBeanName(
         internalCache.getDistributedSystem().getDistributedMember(), lockService.getName());
 
-    LockServiceMXBean bean = service.getLocalLockServiceMBean(lockService.getName());
+    service.unregisterMBean(objectName);
 
-    service.unregisterMBean(lockServiceMBeanName);
-
-    Notification notification = new Notification(JMXNotificationType.LOCK_SERVICE_CLOSED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.LOCK_SERVICE_CLOSED_PREFIX + lockService.getName());
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(LOCK_SERVICE_CLOSED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        LOCK_SERVICE_CLOSED_PREFIX + lockService.getName());
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
   /**
    * Handles management side call backs for a locator creation and start. Assumption is a cache will
    * be created before hand.
    *
+   * <p>
    * There is no corresponding handleStopLocator() method. Locator will close the cache whenever its
    * stopped and it should also shutdown all the management services by closing the cache.
    *
    * @param locator instance of locator which is getting started
    */
-  protected void handleLocatorStart(Locator locator) throws ManagementException {
+  void handleLocatorStart(Locator locator) throws ManagementException {
     if (!isServiceInitialised("handleLocatorCreation")) {
       return;
     }
 
-    ObjectName locatorMBeanName = MBeanJMXAdapter
+    ObjectName objectName = MBeanJMXAdapter
         .getLocatorMBeanName(internalCache.getDistributedSystem().getDistributedMember());
+    LocatorMBeanBridge locatorMBeanBridge = new LocatorMBeanBridge(locator);
+    LocatorMBean locatorMBean = new LocatorMBean(locatorMBeanBridge);
+    ObjectName federatedName = service.registerInternalMBean(locatorMBean, objectName);
+    service.federate(federatedName, LocatorMXBean.class, true);
 
-    LocatorMBeanBridge bridge = new LocatorMBeanBridge(locator);
-    LocatorMBean locatorMBean = new LocatorMBean(bridge);
-
-    ObjectName changedMBeanName = service.registerInternalMBean(locatorMBean, locatorMBeanName);
-
-    service.federate(changedMBeanName, LocatorMXBean.class, true);
-
-    Notification notification =
-        new Notification(JMXNotificationType.LOCATOR_STARTED, memberSource, SequenceNumber.next(),
-            System.currentTimeMillis(), ManagementConstants.LOCATOR_STARTED_PREFIX);
-
-    memberLevelNotifEmitter.sendNotification(notification);
-
+    Notification notification = new Notification(LOCATOR_STARTED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(), LOCATOR_STARTED_PREFIX);
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  protected void handleGatewaySenderStart(GatewaySender sender) throws ManagementException {
+  void handleGatewaySenderStart(GatewaySender gatewaySender) throws ManagementException {
     if (!isServiceInitialised("handleGatewaySenderStart")) {
       return;
     }
-    if ((sender.getRemoteDSId() < 0)) {
+    if (gatewaySender.getRemoteDSId() < 0) {
       return;
     }
-    GatewaySenderMBean bean =
-        (GatewaySenderMBean) service.getLocalGatewaySenderMXBean(sender.getId());
 
-    bean.getBridge().setDispatcher();
+    GatewaySenderMBean gatewaySenderMBean =
+        (GatewaySenderMBean) service.getLocalGatewaySenderMXBean(gatewaySender.getId());
 
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_SENDER_STARTED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_SENDER_STARTED_PREFIX + sender.getId());
+    gatewaySenderMBean.getBridge().setDispatcher();
 
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_SENDER_STARTED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        GATEWAY_SENDER_STARTED_PREFIX + gatewaySender.getId());
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  protected void handleGatewaySenderStop(GatewaySender sender) throws ManagementException {
+  void handleGatewaySenderStop(GatewaySender gatewaySender) throws ManagementException {
     if (!isServiceInitialised("handleGatewaySenderStop")) {
       return;
     }
 
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_SENDER_STOPPED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_SENDER_STOPPED_PREFIX + sender.getId());
-
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_SENDER_STOPPED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        GATEWAY_SENDER_STOPPED_PREFIX + gatewaySender.getId());
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  protected void handleGatewaySenderPaused(GatewaySender sender) throws ManagementException {
+  void handleGatewaySenderPaused(GatewaySender gatewaySender) throws ManagementException {
     if (!isServiceInitialised("handleGatewaySenderPaused")) {
       return;
     }
 
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_SENDER_PAUSED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_SENDER_PAUSED_PREFIX + sender.getId());
-
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_SENDER_PAUSED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        GATEWAY_SENDER_PAUSED_PREFIX + gatewaySender.getId());
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  protected void handleGatewaySenderResumed(GatewaySender sender) throws ManagementException {
+  void handleGatewaySenderResumed(GatewaySender gatewaySender) throws ManagementException {
     if (!isServiceInitialised("handleGatewaySenderResumed")) {
       return;
     }
 
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_SENDER_RESUMED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_SENDER_RESUMED_PREFIX + sender.getId());
-
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_SENDER_RESUMED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        GATEWAY_SENDER_RESUMED_PREFIX + gatewaySender.getId());
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  protected void handleGatewaySenderRemoved(GatewaySender sender) throws ManagementException {
+  void handleGatewaySenderRemoved(GatewaySender gatewaySender) throws ManagementException {
     if (!isServiceInitialised("handleGatewaySenderRemoved")) {
       return;
     }
-    if ((sender.getRemoteDSId() < 0)) {
+    if (gatewaySender.getRemoteDSId() < 0) {
       return;
     }
 
-    GatewaySenderMBean bean =
-        (GatewaySenderMBean) service.getLocalGatewaySenderMXBean(sender.getId());
-    bean.stopMonitor();
+    GatewaySenderMBean gatewaySenderMBean =
+        (GatewaySenderMBean) service.getLocalGatewaySenderMXBean(gatewaySender.getId());
+    gatewaySenderMBean.stopMonitor();
 
-    ObjectName gatewaySenderName = MBeanJMXAdapter.getGatewaySenderMBeanName(
-        internalCache.getDistributedSystem().getDistributedMember(), sender.getId());
-    service.unregisterMBean(gatewaySenderName);
+    ObjectName objectName = MBeanJMXAdapter.getGatewaySenderMBeanName(
+        internalCache.getDistributedSystem().getDistributedMember(), gatewaySender.getId());
+    service.unregisterMBean(objectName);
 
-    Notification notification = new Notification(JMXNotificationType.GATEWAY_SENDER_REMOVED,
-        memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-        ManagementConstants.GATEWAY_SENDER_REMOVED_PREFIX + sender.getId());
-    memberLevelNotifEmitter.sendNotification(notification);
+    Notification notification = new Notification(GATEWAY_SENDER_REMOVED, memberSource,
+        SequenceNumber.next(), System.currentTimeMillis(),
+        GATEWAY_SENDER_REMOVED_PREFIX + gatewaySender.getId());
+    memberLevelNotificationEmitter.sendNotification(notification);
   }
 
-  protected void handleCacheServiceCreation(CacheService cacheService) throws ManagementException {
+  void handleCacheServiceCreation(CacheService cacheService) throws ManagementException {
     if (!isServiceInitialised("handleCacheServiceCreation")) {
       return;
     }
+
     // Don't register the CacheServices in the Locator
     InternalDistributedMember member =
         internalCache.getInternalDistributedSystem().getDistributedMember();
     if (member.getVmKind() == ClusterDistributionManager.LOCATOR_DM_TYPE) {
       return;
     }
-    CacheServiceMBeanBase mbean = cacheService.getMBean();
-    if (mbean != null) {
-      String id = mbean.getId();
-      ObjectName cacheServiceObjectName = MBeanJMXAdapter.getCacheServiceMBeanName(member, id);
 
-      ObjectName changedMBeanName = service.registerInternalMBean(mbean, cacheServiceObjectName);
+    CacheServiceMBeanBase cacheServiceMBean = cacheService.getMBean();
+    if (cacheServiceMBean != null) {
+      String id = cacheServiceMBean.getId();
+      ObjectName objectName = MBeanJMXAdapter.getCacheServiceMBeanName(member, id);
+      ObjectName federatedName = service.registerInternalMBean(cacheServiceMBean, objectName);
+      service.federate(federatedName, cacheServiceMBean.getInterfaceClass(), true);
 
-      service.federate(changedMBeanName, mbean.getInterfaceClass(), true);
-
-      Notification notification = new Notification(JMXNotificationType.CACHE_SERVICE_CREATED,
-          memberSource, SequenceNumber.next(), System.currentTimeMillis(),
-          ManagementConstants.CACHE_SERVICE_CREATED_PREFIX + id);
-      memberLevelNotifEmitter.sendNotification(notification);
+      Notification notification = new Notification(CACHE_SERVICE_CREATED, memberSource,
+          SequenceNumber.next(), System.currentTimeMillis(),
+          CACHE_SERVICE_CREATED_PREFIX + id);
+      memberLevelNotificationEmitter.sendNotification(notification);
     }
   }
 
+  private ObjectName aggregateMBeanPattern() {
+    try {
+      return new ObjectName(AGGREGATE_MBEAN_PATTERN);
+    } catch (MalformedObjectNameException | NullPointerException e) {
+      throw new ManagementException(e);
+    }
+  }
+
+  private boolean isServiceInitialised(String method) {
+    if (!serviceInitialised) {
+      if (logger.isDebugEnabled()) {
+        logger.debug("Management Service is not initialised hence returning from {}", method);
+      }
+    }
+
+    return serviceInitialised;
+  }
+
   /**
-   * Private class which acts as a ClientMembershipListener to propagate client joined/left
-   * notifications
+   * Propagates client joined/left notifications
    */
   private static class CacheServerMembershipListenerAdapter
       extends ClientMembershipListenerAdapter {
 
-    private NotificationBroadcasterSupport serverLevelNotifEmitter;
-    private NotificationBroadcasterSupport memberLevelNotifEmitter;
+    private final NotificationBroadcasterSupport serverLevelNotificationEmitter;
+    private final NotificationBroadcasterSupport memberLevelNotificationEmitter;
+    private final String serverSource;
 
-    private String serverSource;
-
-    public CacheServerMembershipListenerAdapter(
-        NotificationBroadcasterSupport serverLevelNotifEmitter,
-        NotificationBroadcasterSupport memberLevelNotifEmitter, ObjectName serverSource) {
-      this.serverLevelNotifEmitter = serverLevelNotifEmitter;
-      this.memberLevelNotifEmitter = memberLevelNotifEmitter;
+    private CacheServerMembershipListenerAdapter(
+        NotificationBroadcasterSupport serverLevelNotificationEmitter,
+        NotificationBroadcasterSupport memberLevelNotificationEmitter,
+        ObjectName serverSource) {
+      this.serverLevelNotificationEmitter = serverLevelNotificationEmitter;
+      this.memberLevelNotificationEmitter = memberLevelNotificationEmitter;
       this.serverSource = serverSource.toString();
     }
 
@@ -1060,11 +1031,12 @@
      */
     @Override
     public void memberJoined(ClientMembershipEvent event) {
-      Notification notification = new Notification(JMXNotificationType.CLIENT_JOINED, serverSource,
+      Notification notification = new Notification(CLIENT_JOINED, serverSource,
           SequenceNumber.next(), System.currentTimeMillis(),
-          ManagementConstants.CLIENT_JOINED_PREFIX + event.getMemberId());
-      serverLevelNotifEmitter.sendNotification(notification);
-      memberLevelNotifEmitter.sendNotification(notification);
+          CLIENT_JOINED_PREFIX + event.getMemberId());
+
+      serverLevelNotificationEmitter.sendNotification(notification);
+      memberLevelNotificationEmitter.sendNotification(notification);
     }
 
     /**
@@ -1073,11 +1045,12 @@
      */
     @Override
     public void memberLeft(ClientMembershipEvent event) {
-      Notification notification = new Notification(JMXNotificationType.CLIENT_LEFT, serverSource,
+      Notification notification = new Notification(CLIENT_LEFT, serverSource,
           SequenceNumber.next(), System.currentTimeMillis(),
-          ManagementConstants.CLIENT_LEFT_PREFIX + event.getMemberId());
-      serverLevelNotifEmitter.sendNotification(notification);
-      memberLevelNotifEmitter.sendNotification(notification);
+          CLIENT_LEFT_PREFIX + event.getMemberId());
+
+      serverLevelNotificationEmitter.sendNotification(notification);
+      memberLevelNotificationEmitter.sendNotification(notification);
     }
 
     /**
@@ -1086,24 +1059,12 @@
      */
     @Override
     public void memberCrashed(ClientMembershipEvent event) {
-      Notification notification = new Notification(JMXNotificationType.CLIENT_CRASHED, serverSource,
+      Notification notification = new Notification(CLIENT_CRASHED, serverSource,
           SequenceNumber.next(), System.currentTimeMillis(),
-          ManagementConstants.CLIENT_CRASHED_PREFIX + event.getMemberId());
-      serverLevelNotifEmitter.sendNotification(notification);
-      memberLevelNotifEmitter.sendNotification(notification);
+          CLIENT_CRASHED_PREFIX + event.getMemberId());
+
+      serverLevelNotificationEmitter.sendNotification(notification);
+      memberLevelNotificationEmitter.sendNotification(notification);
     }
-
   }
-
-  private boolean isServiceInitialised(String method) {
-    if (!serviceInitialised) {
-      if (logger.isDebugEnabled()) {
-        logger.debug("Management Service is not initialised hence returning from {}", method);
-      }
-      return false;
-    }
-
-    return true;
-  }
-
 }
diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java
index a82a7fb..12edec3 100644
--- a/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java
+++ b/geode-core/src/main/java/org/apache/geode/management/internal/beans/ManagementListener.java
@@ -128,7 +128,7 @@
           break;
         case CACHE_REMOVE:
           InternalCache removedCache = (InternalCache) resource;
-          adapter.handleCacheRemoval(removedCache);
+          adapter.handleCacheRemoval();
           break;
         case REGION_CREATE:
           Region createdRegion = (Region) resource;
@@ -152,7 +152,7 @@
           break;
         case GATEWAYRECEIVER_DESTROY:
           GatewayReceiver destroyedRecv = (GatewayReceiver) resource;
-          adapter.handleGatewayReceiverDestroy(destroyedRecv);
+          adapter.handleGatewayReceiverDestroy();
           break;
         case GATEWAYRECEIVER_START:
           GatewayReceiver startedRecv = (GatewayReceiver) resource;
@@ -160,7 +160,7 @@
           break;
         case GATEWAYRECEIVER_STOP:
           GatewayReceiver stoppededRecv = (GatewayReceiver) resource;
-          adapter.handleGatewayReceiverStop(stoppededRecv);
+          adapter.handleGatewayReceiverStop();
           break;
         case GATEWAYSENDER_CREATE:
           GatewaySender sender = (GatewaySender) resource;
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherTest.java b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherTest.java
index b0245e6..afc0b43 100755
--- a/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/ServerLauncherTest.java
@@ -317,8 +317,9 @@
     when(cache.getCacheServers()).thenReturn(Collections.singletonList(cacheServer1));
     when(cache.addCacheServer()).thenReturn(cacheServer1);
     ServerLauncher launcher = new Builder()
-        .setServerLauncherCacheProvider((a, b) -> cache)
         .setControllableProcessFactory(() -> mock(ControllableProcess.class))
+        .setDisableDefaultServer(true)
+        .setServerLauncherCacheProvider((a, b) -> cache)
         .build();
 
     launcher.start();
@@ -334,10 +335,11 @@
     InternalResourceManager internalResourceManager = mock(InternalResourceManager.class);
     Cache cache = createCache(internalResourceManager);
     ServerLauncher serverLauncher = new Builder()
+        .setControllableProcessFactory(() -> mock(ControllableProcess.class))
+        .setDisableDefaultServer(true)
+        .setServerLauncherCacheProvider((a, b) -> cache)
         .setStartupCompletionAction(startupCompletionAction)
         .setStartupExceptionAction(startupExceptionAction)
-        .setServerLauncherCacheProvider((a, b) -> cache)
-        .setControllableProcessFactory(() -> mock(ControllableProcess.class))
         .build();
 
     when(internalResourceManager.allOfStartupTasks())
@@ -357,9 +359,10 @@
     InternalResourceManager internalResourceManager = mock(InternalResourceManager.class);
     Cache cache = createCache(internalResourceManager);
     ServerLauncher serverLauncher = new Builder()
-        .setStartupExceptionAction(startupExceptionAction)
-        .setServerLauncherCacheProvider((a, b) -> cache)
         .setControllableProcessFactory(() -> mock(ControllableProcess.class))
+        .setDisableDefaultServer(true)
+        .setServerLauncherCacheProvider((a, b) -> cache)
+        .setStartupExceptionAction(startupExceptionAction)
         .build();
 
     when(internalResourceManager.allOfStartupTasks())
@@ -379,8 +382,9 @@
     when(serverLauncherCacheProvider.createCache(any(), any())).thenReturn(cacheFromBuilder);
 
     ServerLauncher serverLauncher = new Builder()
-        .setServerLauncherCacheProvider(serverLauncherCacheProvider)
         .setControllableProcessFactory(() -> mock(ControllableProcess.class))
+        .setDisableDefaultServer(true)
+        .setServerLauncherCacheProvider(serverLauncherCacheProvider)
         .build();
     serverLauncher.start();
 
@@ -396,8 +400,9 @@
     when(serverLauncherCacheProvider.createCache(any(), any())).thenReturn(cacheFromBuilder);
 
     ServerLauncher serverLauncher = new Builder()
-        .setServerLauncherCacheProvider(serverLauncherCacheProvider)
         .setControllableProcessFactory(() -> controllableProcess)
+        .setDisableDefaultServer(true)
+        .setServerLauncherCacheProvider(serverLauncherCacheProvider)
         .build();
     serverLauncher.start();
 
diff --git a/geode-core/src/test/java/org/apache/geode/internal/monitoring/executor/AbstractExecutorGroupJUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/monitoring/executor/AbstractExecutorGroupJUnitTest.java
index de57c32..ece6c95 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/monitoring/executor/AbstractExecutorGroupJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/monitoring/executor/AbstractExecutorGroupJUnitTest.java
@@ -18,8 +18,10 @@
 
 import org.junit.Test;
 
+import org.apache.geode.test.awaitility.GeodeAwaitility;
+
 /**
- * Contains simple tests for the {@link ThreadMonitoringUtils}.
+ * Contains simple tests for the {@link AbstractExecutor}.
  *
  *
  * @since Geode 1.5
@@ -29,6 +31,8 @@
   private final AbstractExecutor abstractExecutorGroup =
       new FunctionExecutionPooledExecutorGroup(null);
 
+  private static final long timeoutInMilliseconds = GeodeAwaitility.getTimeout().getValueInMS();
+
   @Test
   public void testInitializationValues() {
     assertTrue(abstractExecutorGroup.getStartTime() <= System.currentTimeMillis());
@@ -41,4 +45,63 @@
     abstractExecutorGroup.handleExpiry(12);
     assertTrue(abstractExecutorGroup.getNumIterationsStuck() == 1);
   }
+
+  /**
+   * If a thread is blocked by another thread we want to see the other thread's
+   * stack in a "stuck thread" report. This test creates such a thread and
+   * generates a "stuck thread" report to make sure the report on the other thread
+   * is included.
+   */
+  @Test
+  public void lockOwnerThreadStackIsReported() throws InterruptedException {
+    final Object syncObject = new Object();
+    final Object releaseObject = new Object();
+    final boolean[] blockingThreadWaiting = new boolean[1];
+    final boolean[] blockedThreadWaiting = new boolean[1];
+    Thread blockingThread = new Thread("blocking thread") {
+      public void run() {
+        synchronized (syncObject) {
+          synchronized (releaseObject) {
+            try {
+              blockingThreadWaiting[0] = true;
+              releaseObject.wait(timeoutInMilliseconds);
+            } catch (InterruptedException e) {
+              return;
+            }
+          }
+        }
+      }
+    };
+    Thread blockedThread = new Thread("blocked thread") {
+      public void run() {
+        blockedThreadWaiting[0] = true;
+        synchronized (syncObject) {
+          try {
+            syncObject.wait(timeoutInMilliseconds);
+          } catch (InterruptedException e) {
+            return;
+          }
+        }
+      }
+    };
+    blockingThread.start();
+    GeodeAwaitility.await().until(() -> blockingThreadWaiting[0]);
+    blockedThread.start();
+    GeodeAwaitility.await().until(() -> blockedThreadWaiting[0]);
+    try {
+      AbstractExecutor executor = new AbstractExecutor(null, blockedThread.getId()) {
+        @Override
+        public void handleExpiry(long stuckTime) {
+          // no-op
+        }
+      };
+      String threadReport = executor.createThreadReport(60000);
+      assertTrue(threadReport.contains(AbstractExecutor.LOCK_OWNER_THREAD_STACK));
+    } finally {
+      blockingThread.interrupt();
+      blockedThread.interrupt();
+      blockingThread.join(timeoutInMilliseconds);
+      blockedThread.join(timeoutInMilliseconds);
+    }
+  }
 }
diff --git a/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java b/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java
index b776bed..c233935 100644
--- a/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java
+++ b/geode-core/src/test/java/org/apache/geode/management/internal/FederatingManagerTest.java
@@ -17,6 +17,7 @@
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 import static org.powermock.api.mockito.PowerMockito.when;
@@ -25,42 +26,47 @@
 
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.experimental.categories.Category;
 import org.mockito.ArgumentCaptor;
 
 import org.apache.geode.StatisticsFactory;
 import org.apache.geode.alerting.internal.spi.AlertLevel;
 import org.apache.geode.cache.Region;
+import org.apache.geode.cache.RegionDestroyedException;
 import org.apache.geode.distributed.internal.DistributionManager;
 import org.apache.geode.distributed.internal.InternalDistributedSystem;
 import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
-import org.apache.geode.internal.cache.HasCachePerfStats;
 import org.apache.geode.internal.cache.InternalCache;
 import org.apache.geode.internal.cache.InternalCacheForClientAccess;
 import org.apache.geode.internal.cache.InternalRegionArguments;
+import org.apache.geode.internal.logging.LoggingExecutors;
 import org.apache.geode.internal.statistics.StatisticsClock;
 import org.apache.geode.management.DistributedSystemMXBean;
+import org.apache.geode.test.junit.categories.JMXTest;
 
+@Category(JMXTest.class)
 public class FederatingManagerTest {
 
+  private InternalCache cache;
+  private InternalCacheForClientAccess cacheForClientAccess;
   private MBeanJMXAdapter jmxAdapter;
   private ManagementResourceRepo repo;
-  private InternalDistributedSystem system;
   private SystemManagementService service;
-  private InternalCache cache;
   private StatisticsFactory statisticsFactory;
   private StatisticsClock statisticsClock;
-  private InternalCacheForClientAccess cacheForClientAccess;
+  private InternalDistributedSystem system;
 
   @Before
   public void setUp() throws Exception {
+    cache = mock(InternalCache.class);
+    cacheForClientAccess = mock(InternalCacheForClientAccess.class);
     jmxAdapter = mock(MBeanJMXAdapter.class);
     repo = mock(ManagementResourceRepo.class);
-    system = mock(InternalDistributedSystem.class);
     service = mock(SystemManagementService.class);
-    cache = mock(InternalCache.class);
-    statisticsFactory = mock(StatisticsFactory.class);
     statisticsClock = mock(StatisticsClock.class);
-    cacheForClientAccess = mock(InternalCacheForClientAccess.class);
+    statisticsFactory = mock(StatisticsFactory.class);
+    system = mock(InternalDistributedSystem.class);
+
     DistributedSystemMXBean distributedSystemMXBean = mock(DistributedSystemMXBean.class);
 
     when(cache.getCacheForProcessingClientRequests())
@@ -77,66 +83,182 @@
 
   @Test
   public void addMemberArtifactsCreatesMonitoringRegion() throws Exception {
-    InternalDistributedMember member = member(1, 20);
-    FederatingManager federatingManager = new FederatingManager(jmxAdapter, repo, system, service,
-        cache, statisticsFactory, statisticsClock);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
     federatingManager.startManager();
 
-    federatingManager.addMemberArtifacts(member);
+    federatingManager.addMemberArtifacts(member(1, 20));
 
-    verify(cacheForClientAccess).createInternalRegion(eq("_monitoringRegion_null<v1>20"), any(),
-        any());
+    verify(cacheForClientAccess)
+        .createInternalRegion(eq("_monitoringRegion_null<v1>20"), any(), any());
   }
 
   @Test
   public void addMemberArtifactsCreatesMonitoringRegionWithHasOwnStats() throws Exception {
-    InternalDistributedMember member = member(2, 40);
-    FederatingManager federatingManager = new FederatingManager(jmxAdapter, repo, system, service,
-        cache, statisticsFactory, statisticsClock);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
     federatingManager.startManager();
 
-    federatingManager.addMemberArtifacts(member);
+    federatingManager.addMemberArtifacts(member(2, 40));
 
     ArgumentCaptor<InternalRegionArguments> captor =
         ArgumentCaptor.forClass(InternalRegionArguments.class);
-    verify(cacheForClientAccess).createInternalRegion(eq("_monitoringRegion_null<v2>40"), any(),
-        captor.capture());
-
-    InternalRegionArguments internalRegionArguments = captor.getValue();
-    HasCachePerfStats hasCachePerfStats = internalRegionArguments.getCachePerfStatsHolder();
-    assertThat(hasCachePerfStats.hasOwnStats()).isTrue();
+    verify(cacheForClientAccess)
+        .createInternalRegion(eq("_monitoringRegion_null<v2>40"), any(), captor.capture());
+    boolean hasOwnStats = captor.getValue().getCachePerfStatsHolder().hasOwnStats();
+    assertThat(hasOwnStats)
+        .isTrue();
   }
 
   @Test
   public void addMemberArtifactsCreatesNotificationRegion() throws Exception {
-    InternalDistributedMember member = member(3, 60);
-    FederatingManager federatingManager = new FederatingManager(jmxAdapter, repo, system, service,
-        cache, statisticsFactory, statisticsClock);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
     federatingManager.startManager();
 
-    federatingManager.addMemberArtifacts(member);
+    federatingManager.addMemberArtifacts(member(3, 60));
 
-    verify(cacheForClientAccess).createInternalRegion(eq("_notificationRegion_null<v3>60"), any(),
-        any());
+    verify(cacheForClientAccess)
+        .createInternalRegion(eq("_notificationRegion_null<v3>60"), any(), any());
   }
 
   @Test
   public void addMemberArtifactsCreatesNotificationRegionWithHasOwnStats() throws Exception {
-    InternalDistributedMember member = member(4, 80);
-    FederatingManager federatingManager = new FederatingManager(jmxAdapter, repo, system, service,
-        cache, statisticsFactory, statisticsClock);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
     federatingManager.startManager();
 
-    federatingManager.addMemberArtifacts(member);
+    federatingManager.addMemberArtifacts(member(4, 80));
 
     ArgumentCaptor<InternalRegionArguments> captor =
         ArgumentCaptor.forClass(InternalRegionArguments.class);
-    verify(cacheForClientAccess).createInternalRegion(eq("_notificationRegion_null<v4>80"), any(),
-        captor.capture());
+    verify(cacheForClientAccess)
+        .createInternalRegion(eq("_notificationRegion_null<v4>80"), any(), captor.capture());
 
     InternalRegionArguments internalRegionArguments = captor.getValue();
-    HasCachePerfStats hasCachePerfStats = internalRegionArguments.getCachePerfStatsHolder();
-    assertThat(hasCachePerfStats.hasOwnStats()).isTrue();
+    assertThat(internalRegionArguments.getCachePerfStatsHolder().hasOwnStats())
+        .isTrue();
+  }
+
+  @Test
+  public void removeMemberArtifactsLocallyDestroysMonitoringRegion() {
+    InternalDistributedMember member = member();
+    Region monitoringRegion = mock(Region.class);
+    when(repo.getEntryFromMonitoringRegionMap(eq(member)))
+        .thenReturn(monitoringRegion);
+    when(repo.getEntryFromNotifRegionMap(eq(member)))
+        .thenReturn(mock(Region.class));
+    when(system.getDistributedMember())
+        .thenReturn(member);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
+
+    federatingManager.removeMemberArtifacts(member, false);
+
+    verify(monitoringRegion)
+        .localDestroyRegion();
+  }
+
+  @Test
+  public void removeMemberArtifactsLocallyDestroysNotificationRegion() {
+    InternalDistributedMember member = member();
+    Region notificationRegion = mock(Region.class);
+    when(repo.getEntryFromMonitoringRegionMap(eq(member)))
+        .thenReturn(mock(Region.class));
+    when(repo.getEntryFromNotifRegionMap(eq(member)))
+        .thenReturn(notificationRegion);
+    when(system.getDistributedMember())
+        .thenReturn(member);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
+
+    federatingManager.removeMemberArtifacts(member, false);
+
+    verify(notificationRegion)
+        .localDestroyRegion();
+  }
+
+  @Test
+  public void removeMemberArtifactsDoesNotThrowIfMonitoringRegionIsAlreadyDestroyed() {
+    InternalDistributedMember member = member();
+    Region monitoringRegion = mock(Region.class);
+    doThrow(new RegionDestroyedException("test", "monitoringRegion"))
+        .when(monitoringRegion).localDestroyRegion();
+    when(repo.getEntryFromMonitoringRegionMap(eq(member)))
+        .thenReturn(monitoringRegion);
+    when(repo.getEntryFromNotifRegionMap(eq(member)))
+        .thenReturn(mock(Region.class));
+    when(system.getDistributedMember())
+        .thenReturn(member);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
+
+    federatingManager.removeMemberArtifacts(member, false);
+
+    verify(monitoringRegion)
+        .localDestroyRegion();
+  }
+
+  @Test
+  public void removeMemberArtifactsDoesNotThrowIfNotificationRegionIsAlreadyDestroyed() {
+    InternalDistributedMember member = member();
+    Region notificationRegion = mock(Region.class);
+    doThrow(new RegionDestroyedException("test", "notificationRegion"))
+        .when(notificationRegion).localDestroyRegion();
+    when(repo.getEntryFromMonitoringRegionMap(eq(member)))
+        .thenReturn(mock(Region.class));
+    when(repo.getEntryFromNotifRegionMap(eq(member)))
+        .thenReturn(notificationRegion);
+    when(system.getDistributedMember())
+        .thenReturn(member);
+    FederatingManager federatingManager = new FederatingManager(repo, system, service, cache,
+        statisticsFactory, statisticsClock,
+        new MBeanProxyFactory(jmxAdapter, service),
+        new MemberMessenger(jmxAdapter, system),
+        LoggingExecutors.newFixedThreadPool("FederatingManager", true,
+            Runtime.getRuntime().availableProcessors()));
+
+    federatingManager.removeMemberArtifacts(member, false);
+
+    verify(notificationRegion)
+        .localDestroyRegion();
+  }
+
+  @Test
+  public void removeMemberArtifactsDoesNotThrowIfMBeanProxyFactoryThrowsRegionDestroyedException() {
+
+  }
+
+  private InternalDistributedMember member() {
+    return member(1, 1);
   }
 
   private InternalDistributedMember member(int viewId, int port) {
diff --git a/geode-docs/configuring/running/default_file_specs.html.md.erb b/geode-docs/configuring/running/default_file_specs.html.md.erb
index f4e3698..65b830e 100644
--- a/geode-docs/configuring/running/default_file_specs.html.md.erb
+++ b/geode-docs/configuring/running/default_file_specs.html.md.erb
@@ -40,7 +40,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">gemfire.properties</code></td>
 <td><ol>
 <li>current directory</li>
@@ -49,7 +49,7 @@
 </ol></td>
 <td>As a Java system property, use <code class="ph codeph">gemfirePropertyFile</code></td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">cache.xml</code></td>
 <td><ol>
 <li>current directory</li>
diff --git a/geode-docs/configuring/running/firewalls_ports.html.md.erb b/geode-docs/configuring/running/firewalls_ports.html.md.erb
index 96dca63..2a66934 100644
--- a/geode-docs/configuring/running/firewalls_ports.html.md.erb
+++ b/geode-docs/configuring/running/firewalls_ports.html.md.erb
@@ -57,32 +57,32 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>peer-to-peer config</td>
 <td><p><code class="ph codeph">conserve-sockets</code></p></td>
 <td><p>Specifies whether sockets are shared by the system member's threads.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>peer-to-peer config</td>
 <td><p><code class="ph codeph">locators</code></p></td>
 <td><p>The list of locators used by system members. The list must be configured consistently for every member of the cluster.</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>peer-to-peer config</td>
 <td><p><code class="ph codeph">mcast-address</code></p></td>
 <td><p>Address used to discover other members of the cluster. Only used if mcast-port is non-zero. This attribute must be consistent across the cluster.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>peer-to-peer config</td>
 <td><p><code class="ph codeph">mcast-port</code></p></td>
 <td><p>Port used, along with the mcast-address, for multicast communication with other members of the cluster. If zero, multicast is disabled for data distribution.</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>peer-to-peer config</td>
 <td><p><code class="ph codeph">membership-port-range</code></p></td>
 <td><p>The range of ephemeral ports available for unicast UDP messaging and for TCP failure detection in the peer-to-peer cluster.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>peer-to-peer config</td>
 <td><p><code class="ph codeph">tcp-port</code></p></td>
 <td><p>The TCP port to listen on for cache communications.</p></td>
@@ -104,17 +104,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>cache server config</td>
 <td><p><code class="ph codeph">hostname-for-clients</code></p></td>
 <td><p>Hostname or IP address to pass to the client as the location where the server is listening.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>cache server config</td>
 <td><p><code class="ph codeph">max-connections</code></p></td>
 <td><p>Maximum number of client connections for the server. When the maximum is reached, the server refuses additional client connections.</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>cache server config</td>
 <td><p><code class="ph codeph">port</code> (cache.xml) or <code class="ph codeph">--port</code> parameter to the <code class="ph codeph">gfsh start server</code> command</p></td>
 <td><p>Port that the server listens on for client communication.</p></td>
@@ -138,42 +138,42 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><p>Cache Server</p></td>
 <td><p><code class="ph codeph">port</code> (cache.xml)</p></td>
 <td>40404</td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>HTTP</p></td>
 <td><code class="ph codeph">http-service-port</code></td>
 <td>7070</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>Locator</p></td>
 <td><code class="ph codeph">start-locator</code> (for embedded locators) or <code class="ph codeph">--port</code> parameter to the <code class="ph codeph">gfsh start locator</code> command.</td>
 <td><em>if not specified upon startup or in the start-locator property, uses default port 10334</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>Membership Port Range</p></td>
 <td><code class="ph codeph">membership-port-range</code></td>
 <td>41000 to 61000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>Memcached Port</p></td>
 <td><code class="ph codeph">memcached-port</code></td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>Multicast</p></td>
 <td><code class="ph codeph">mcast-port</code></td>
 <td>10334</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>RMI</p></td>
 <td><code class="ph codeph">jmx-manager-port</code></td>
 <td>1099</td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>TCP</p></td>
 <td><code class="ph codeph">tcp-port</code></td>
 <td>ephemeral port</td>
diff --git a/geode-docs/developing/events/how_client_server_distribution_works.html.md.erb b/geode-docs/developing/events/how_client_server_distribution_works.html.md.erb
index 214f1ec..7398959 100644
--- a/geode-docs/developing/events/how_client_server_distribution_works.html.md.erb
+++ b/geode-docs/developing/events/how_client_server_distribution_works.html.md.erb
@@ -67,17 +67,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>Entry create/update</td>
 <td>For subscriptions with <code class="ph codeph">receiveValues</code> set to true, entry create or update.
 <p></p>
 For subscriptions with <code class="ph codeph">receiveValues</code> set to false, entry invalidate if the entry already exists in the client cache; otherwise, no effect. The next client get for the entry is forwarded to the server.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Entry invalidate/destroy (distributed only)</td>
 <td>Entry invalidate/destroy</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Region destroy/clear (distributed only)</td>
 <td>Region destroy or local region clear</td>
 </tr>
diff --git a/geode-docs/developing/query_select/the_select_statement.html.md.erb b/geode-docs/developing/query_select/the_select_statement.html.md.erb
index 67458ff..f675ed9 100644
--- a/geode-docs/developing/query_select/the_select_statement.html.md.erb
+++ b/geode-docs/developing/query_select/the_select_statement.html.md.erb
@@ -140,33 +140,33 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>ELEMENT(expr)</td>
 <td>Extracts a single element from a collection or array. This function throws a <code class="ph codeph">FunctionDomainException</code> if the argument is not a collection or array with exactly one element.</td>
 <td><pre class="pre codeblock"><code>ELEMENT(SELECT DISTINCT * 
  FROM /exampleRegion 
  WHERE id = &#39;XYZ-1&#39;).status = &#39;active&#39;</code></pre></td>
 </tr>
-<tr class="even">
+<tr>
 <td>IS_DEFINED(expr)</td>
 <td>Returns TRUE if the expression does not evaluate to <a href="../query_additional/literals.html#literals__section_undefined">UNDEFINED</a>.  Inequality queries include undefined values in their query results. With the IS_DEFINED function, you can limit results to only those elements with defined values.</td>
 <td><pre class="pre codeblock"><code>IS_DEFINED(SELECT DISTINCT * 
 FROM /exampleRegion p 
 WHERE p.status = &#39;active&#39;)</code></pre></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>IS_UNDEFINED (expr)</td>
 <td>Returns TRUE if the expression evaluates to <a href="../query_additional/literals.html#literals__section_undefined">UNDEFINED</a>. With the exception of inequality queries, most queries do not include undefined values in their query results. The IS_UNDEFINED function allows undefined values to be included, so you can identify elements with undefined values.</td>
 <td><pre class="pre codeblock"><code>SELECT DISTINCT * 
 FROM /exampleRegion p 
 WHERE IS_UNDEFINED(p.status)</code></pre></td>
 </tr>
-<tr class="even">
+<tr>
 <td>NVL(expr1, expr2)</td>
 <td>Returns expr2 if expr1 is null. The expressions can be query parameters (bind arguments), path expressions, or literals.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>TO_DATE(date_str, format_str)</td>
 <td>Returns a Java Data class object. The arguments must be String S with date_str representing the date and format_str representing the format used by date_str. The format_str you provide is parsed using java.text.SimpleDateFormat.</td>
 <td> </td>
diff --git a/geode-docs/developing/querying_basics/what_is_a_query_string.html.md.erb b/geode-docs/developing/querying_basics/what_is_a_query_string.html.md.erb
index f12729b..8d94a69 100644
--- a/geode-docs/developing/querying_basics/what_is_a_query_string.html.md.erb
+++ b/geode-docs/developing/querying_basics/what_is_a_query_string.html.md.erb
@@ -47,4 +47,6 @@
 
 -   **[SELECT Statement](../query_select/the_select_statement.html)**
 
+-   **[OQL Aggregate Functions](../query_select/aggregates.html)**
+
 
diff --git a/geode-docs/developing/region_options/region_types.html.md.erb b/geode-docs/developing/region_options/region_types.html.md.erb
index 60f0bf0..8117f0e 100644
--- a/geode-docs/developing/region_options/region_types.html.md.erb
+++ b/geode-docs/developing/region_options/region_types.html.md.erb
@@ -50,7 +50,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>Partitioned</td>
 <td>System-wide setting for the data set. Data is divided into buckets across the members that define the region. For high availability, configure redundant copies so each bucket is stored in multiple members with one member holding the primary.</td>
 <td>Server regions and peer regions
@@ -61,7 +61,7 @@
 <li>Partitioned event listeners and data loaders</li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td>Replicated (distributed)</td>
 <td>Holds all data from the distributed region. The data from the distributed region is copied into the member replica region. Can be mixed with non-replication, with some members holding replicas and some holding non-replicas.</td>
 <td>Server regions and peer regions
@@ -71,7 +71,7 @@
 <li>Query performance</li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Distributed non-replicated</td>
 <td>Data is spread across the members that define the region. Each member holds only the data it has expressed interest in. Can be mixed with replication, with some members holding replicas and some holding non-replicas.</td>
 <td>Peer regions, but not server regions and not client regions
@@ -80,7 +80,7 @@
 <li>Query performance</li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td>Non-distributed (local)</td>
 <td>The region is visible only to the defining member.</td>
 <td>Client regions and peer regions
diff --git a/geode-docs/getting_started/setup_classpath.html.md.erb b/geode-docs/getting_started/setup_classpath.html.md.erb
index d33fdfa..152c08b 100644
--- a/geode-docs/getting_started/setup_classpath.html.md.erb
+++ b/geode-docs/getting_started/setup_classpath.html.md.erb
@@ -47,11 +47,11 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>gfsh</td>
 <td>gfsh-dependencies.jar</td>
 </tr>
-<tr class="even">
+<tr>
 <td>server and locator</td>
 <td>geode-dependencies.jar
 <div class="note note">
diff --git a/geode-docs/managing/disk_storage/disk_store_configuration_params.html.md.erb b/geode-docs/managing/disk_storage/disk_store_configuration_params.html.md.erb
index 25f2083..bfb4d55 100644
--- a/geode-docs/managing/disk_storage/disk_store_configuration_params.html.md.erb
+++ b/geode-docs/managing/disk_storage/disk_store_configuration_params.html.md.erb
@@ -39,54 +39,54 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">name</code></td>
 <td>String used to identify this disk store. All regions and queues select their disk store by specifying this name.</td>
 <td>DEFAULT</td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">allow-force-compaction</code></td>
 <td>Boolean indicating whether to allow manual compaction through the API or command-line tools.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">auto-compact</code></td>
 <td>Boolean indicating whether to automatically compact a file when it reaches the <code class="ph codeph">compaction-threshold</code>.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">compaction-threshold</code></td>
 <td>Percentage of garbage allowed in the file before it is eligible for compaction. Garbage is created by entry destroys, entry updates, and region destroys and creates. Surpassing this percentage does not make compaction occur—it makes the file eligible to be compacted when a compaction is done.</td>
 <td>50</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">disk-usage-critical-percentage</code></td>
 <td>Disk usage above this threshold generates an error message and shuts down the member's cache. For example, if the threshold is set to 99%, then falling under 10 GB of free disk space on a 1 TB drive generates the error and shuts down the cache.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
 <td>99</td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">disk-usage-warning-percentage</code></td>
 <td>Disk usage above this threshold generates a warning message. For example, if the threshold is set to 90%, then on a 1 TB drive falling under 100 GB of free disk space generates the warning.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
 <td>90</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">max-oplog-size</code></td>
 <td>The largest size, in megabytes, to allow an operation log to become before automatically rolling to a new file. This size is the combined sizes of the oplog files.</td>
 <td>1024</td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">queue-size</code></td>
 <td>For asynchronous queueing. The maximum number of operations to allow into the write queue before automatically flushing the queue. Operations that would add entries to the queue block until the queue is flushed. A value of zero implies no size limit. Reaching this limit or the time-interval limit will cause the queue to flush.</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">time-interval</code></td>
 <td>For asynchronous queueing. The number of milliseconds that can elapse before data is flushed to disk. Reaching this limit or the queue-size limit causes the queue to flush.</td>
 <td>1000</td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">write-buffer-size</code></td>
 <td>Size of the buffer, in bytes, used to write to disk.</td>
 <td>32768</td>
diff --git a/geode-docs/managing/logging/configuring_log4j2.html.md.erb b/geode-docs/managing/logging/configuring_log4j2.html.md.erb
index dc01359..78001e2 100644
--- a/geode-docs/managing/logging/configuring_log4j2.html.md.erb
+++ b/geode-docs/managing/logging/configuring_log4j2.html.md.erb
@@ -17,9 +17,9 @@
 limitations under the License.
 -->
 
-Basic <%=vars.product_name%> logging configuration is configured via the gemfire.properties file. This topic is intended for advanced users who need increased control over logging due to integration with third-party libraries.
+Basic <%=vars.product_name%> logging configuration is configured via the `gemfire.properties` file. This topic is intended for advanced users who need increased control over logging due to integration with third-party libraries.
 
-The default `log4j2.xml` that <%=vars.product_name%> uses is stored in geode.jar as `log4j2-default.xml`. The contents of the configuration can be viewed in the product distribution in the following location: `$GEMFIRE/defaultConfigs/log4j2.xml`.
+An example `log4j2.xml` can be located within the product distribution at `$GEODE/config/log4j2.xml`.
 
 To specify your own `log4j2.xml` configuration file (or anything else supported by Log4j 2 such as .json or .yaml), use the following flag when starting up your JVM or <%=vars.product_name%> member:
 
@@ -27,7 +27,8 @@
 -Dlog4j.configurationFile=<location-of-your-file>
 ```
 
-If the Java system property `log4j.configurationFile` is specified, then <%=vars.product_name%> will not use the `log4j2-default.xml` included in geode.jar. However, <%=vars.product_name%> will still create and register a AlertAppender and LogWriterAppender if the `alert-level` and `log-file` <%=vars.product_name%> properties are configured. You can then use the <%=vars.product_name%> LogWriter to log to <%=vars.product_name%>'s log or to generate an Alert and receive log statements from customer's application and all third party libraries. Alternatively, you can use any front-end logging API that is configured to log to Log4j 2.
+If the Java system property `log4j.configurationFile` is specified,
+then Log4j will not use the `log4j2.xml` included in `geode-log4j-<version>.jar`.
 
 ## Using Different Front-End Logging APIs to Log to Log4j2
 
@@ -52,9 +53,9 @@
 
 Custom Log4j 2 configuration in <%=vars.product_name%> comes with some caveats and notes:
 
--   Do not use `"monitorInterval="` in your log4j2.xml file because doing so can have significant performance impact. This setting instructs Log4j 2 to monitor the log4j2.xml config file at runtime and automatically reload and reconfigure if the file changes.
+-   Do not use `"monitorInterval="` in your `log4j2.xml` file, because doing so can have significant performance impact. This setting instructs Log4j 2 to monitor the log4j2.xml config file at runtime and automatically reload and reconfigure if the file changes.
 -   <%=vars.product_name%>'s default `log4j2.xml` specifies status="FATAL" because Log4j 2's StatusLogger generates warnings to standard out at ERROR level anytime <%=vars.product_name%> stops its AlertAppender or LogWriterAppender. <%=vars.product_name%> uses a lot of concurrent threads that are executing code with log statements; these threads may be logging while the <%=vars.product_name%> appenders are being stopped.
--   <%=vars.product_name%>'s default log4j2.xml specifies `shutdownHook="disable"` because <%=vars.product_name%> has a shutdown hook which disconnects the DistributedSystem and closes the Cache, which is executing the code that performs logging. If the Log4J2 shutdown hook stops logging before <%=vars.product_name%> completes its shutdown, Log4j 2 will attempt to start back up. This restart in turn attempts to register another Log4j 2 shutdown hook which fails resulting in a FATAL level message logged by Log4j 2.
+-   <%=vars.product_name%>'s default `log4j2.xml` specifies `shutdownHook="disable"` because <%=vars.product_name%> has a shutdown hook which disconnects the DistributedSystem and closes the Cache, which is executing the code that performs logging. If the Log4J2 shutdown hook stops logging before <%=vars.product_name%> completes its shutdown, Log4j 2 will attempt to start back up. This restart in turn attempts to register another Log4j 2 shutdown hook which fails resulting in a FATAL level message logged by Log4j 2.
 -   The GEODE\_VERBOSE marker (Log4J2 Marker are discussed on [http://logging.apache.org/log4j/2.x/manual/markers.html](http://logging.apache.org/log4j/2.x/manual/markers.html)) can be used to enable additional verbose log statements at TRACE level. Many log statements are enabled simply by enabling DEBUG or TRACE. However, even more log statements can be further enabled by using MarkerFilter to accept GEODE\_VERBOSE. The default <%=vars.product_name%> `log4j2.xml` disables GEODE\_VERBOSE with this line:
 
     ``` pre
diff --git a/geode-docs/managing/management/jmx_manager_operations.html.md.erb b/geode-docs/managing/management/jmx_manager_operations.html.md.erb
index 4f8142c..d357b4c 100644
--- a/geode-docs/managing/management/jmx_manager_operations.html.md.erb
+++ b/geode-docs/managing/management/jmx_manager_operations.html.md.erb
@@ -100,58 +100,58 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>http-service-port</td>
 <td>If non-zero, then <%=vars.product_name%> starts an embedded HTTP service that listens on this port. The HTTP service is used to host the <%=vars.product_name%> Pulse Web application. If you are hosting the Pulse web app on your own Web server, then disable this embedded HTTP service by setting this property to zero. Ignored if <code class="ph codeph">jmx-manager</code> is false.</td>
 <td>7070</td>
 </tr>
-<tr class="even">
+<tr>
 <td>http-service-bind-address</td>
 <td>If set, then the <%=vars.product_name%> member binds the embedded HTTP service to the specified address. If this property is not set but the HTTP service is enabled using <code class="ph codeph">http-service-port</code>, then <%=vars.product_name%> binds the HTTP service to the member's local address.</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jmx-manager</td>
 <td><p>If <code class="ph codeph">true</code> then this member can become a JMX Manager. All other <code class="ph codeph">jmx-manager-*</code> properties are used when it does become a JMX Manager. If this property is false then all other <code class="ph codeph">jmx-manager-*</code> properties are ignored.</p>
 <p>The default value is <code class="ph codeph">true</code> on locators.</p></td>
 <td>false (with Locator exception)</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-access-file</td>
 <td><p>By default the JMX Manager allows full access to all MBeans by any client. If this property is set to the name of a file, then it can restrict clients to only reading MBeans; they cannot modify MBeans. The access level can be configured differently in this file for each user name defined in the password file. For more information about the format of this file see Oracle's documentation of the <code class="ph codeph">com.sun.management.jmxremote.access.file</code> system property. Ignored if <code class="ph codeph">jmx-manager</code> is false or if <code class="ph codeph">jmx-manager-port</code> is zero.</p></td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jmx-manager-bind-address</td>
 <td>By default, the JMX Manager when configured with a port listens on all the local host's addresses. You can use this property to configure which particular IP address or host name the JMX Manager will listen on. This property is ignored if <code class="ph codeph">jmx-manager</code> is false or <code class="ph codeph">jmx-manager-port</code> is zero. This address also applies to the <%=vars.product_name%> Pulse server if you are hosting a Pulse web application.</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-hostname-for-clients</td>
 <td>Hostname given to clients that ask the locator for the location of a JMX Manager. By default the IP address of the JMX Manager is used. However, for clients on a different network, you can configure a different hostname to be given to clients. Ignored if <code class="ph codeph">jmx-manager</code> is false or if <code class="ph codeph">jmx-manager-port</code> is zero.</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jmx-manager-password-file</td>
 <td>By default the JMX Manager allows clients without credentials to connect. If this property is set to the name of a file, only clients that connect with credentials that match an entry in this file will be allowed. Most JVMs require that the file is only readable by the owner. For more information about the format of this file see Oracle's documentation of the com.sun.management.jmxremote.password.file system property. Ignored if jmx-manager is false or if jmx-manager-port is zero. </td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-port</td>
 <td>Port on which this JMX Manager listens for client connections. If this property is set to zero, <%=vars.product_name%> does not allow remote client connections. Alternatively, use the standard system properties supported by the JVM for configuring access from remote JMX clients. Ignored if jmx-manager is false. The Default RMI port is 1099.</td>
 <td>1099</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jmx-manager-ssl</td>
 <td>If true and <code class="ph codeph">jmx-manager-port</code> is not zero, the JMX Manager accepts only SSL connections. The ssl-enabled property does not apply to the JMX Manager, but the other SSL properties do. This allows SSL to be configured for just the JMX Manager without needing to configure it for the other <%=vars.product_name%> connections. Ignored if <code class="ph codeph">jmx-manager</code> is false.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-start</td>
 <td>If true, this member starts a JMX Manager when it creates a cache. In most cases you should not set this property to true because a JMX Manager is automatically started when needed on a member that sets <code class="ph codeph">jmx-manager</code> to true. Ignored if jmx-manager is false.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jmx-manager-update-rate</td>
 <td>The rate, in milliseconds, at which this member pushes updates to any JMX Managers. Currently this value should be greater than or equal to the <code class="ph codeph">statistic-sample-rate</code>. Setting this value too high causes <code class="ph codeph">gfsh</code> and <%=vars.product_name%> Pulse to see stale values.</td>
 <td>2000</td>
diff --git a/geode-docs/managing/monitor_tune/multicast_communication_provisioning_bandwidth.html.md.erb b/geode-docs/managing/monitor_tune/multicast_communication_provisioning_bandwidth.html.md.erb
index 402590f..78f0175 100644
--- a/geode-docs/managing/monitor_tune/multicast_communication_provisioning_bandwidth.html.md.erb
+++ b/geode-docs/managing/monitor_tune/multicast_communication_provisioning_bandwidth.html.md.erb
@@ -42,15 +42,15 @@
 <col width="50%" />
 </colgroup>
 <tbody>
-<tr class="odd">
+<tr>
 <td><p><code class="ph codeph">byteAllowance</code></p></td>
 <td><p>Number of bytes that can be sent without a recharge.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p><code class="ph codeph">rechargeThreshold</code></p></td>
 <td><p>Tells consumers how low the producer’s initial to remaining allowance ratio should be before sending a recharge.</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">rechargeBlockMs</code></td>
 <td><p>Tells the producer how long to wait for a recharge before requesting one.</p></td>
 </tr>
diff --git a/geode-docs/managing/monitor_tune/multicast_communication_testing_multicast_speed_limits.html.md.erb b/geode-docs/managing/monitor_tune/multicast_communication_testing_multicast_speed_limits.html.md.erb
index 4dbdc32..abb6147 100644
--- a/geode-docs/managing/monitor_tune/multicast_communication_testing_multicast_speed_limits.html.md.erb
+++ b/geode-docs/managing/monitor_tune/multicast_communication_testing_multicast_speed_limits.html.md.erb
@@ -46,15 +46,15 @@
 <col width="50%" />
 </colgroup>
 <tbody>
-<tr class="odd">
+<tr>
 <td>-c address</td>
 <td><p>Run in client mode and connect to a multicast address</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>-u</td>
 <td><p>Use UDP</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>-T #</td>
 <td><p>Multicast time-to-live: number of subnets across which a multicast packet can travel before the routers drop the packet</p></td>
 </tr>
@@ -70,15 +70,15 @@
 <col width="50%" />
 </colgroup>
 <tbody>
-<tr class="odd">
+<tr>
 <td>-t</td>
 <td><p>Length of time to transmit, in seconds</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>-i</td>
 <td><p>Time between periodic bandwidth reports, in seconds</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>-b</td>
 <td>Sending bandwidth, in bits per second</td>
 </tr>
@@ -99,19 +99,19 @@
 <col width="50%" />
 </colgroup>
 <tbody>
-<tr class="odd">
+<tr>
 <td><p>-s</p></td>
 <td><p>Run in server mode</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>-u</p></td>
 <td><p>Use UDP</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>-B address</p></td>
 <td><p>Bind to a multicast address</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>-i #</td>
 <td>Time between periodic bandwidth reports, in seconds</td>
 </tr>
diff --git a/geode-docs/managing/monitor_tune/socket_communication_have_enough_sockets.html.md.erb b/geode-docs/managing/monitor_tune/socket_communication_have_enough_sockets.html.md.erb
index 35a3b54..1c52ed5 100644
--- a/geode-docs/managing/monitor_tune/socket_communication_have_enough_sockets.html.md.erb
+++ b/geode-docs/managing/monitor_tune/socket_communication_have_enough_sockets.html.md.erb
@@ -80,24 +80,24 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><p>Membership failure detection</p></td>
 <td>2</td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>Listener for incoming peer connections (server P2P)</p></td>
 <td><p>1</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>Shared sockets (2 in and 2 out)</p>
 <p>Threads that share sockets use these.</p></td>
 <td><p>4 * (M-1)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>This member’s thread-owned sockets (1 in and 1 out for each thread, for each peer member).</td>
 <td><p>(T * 2) * (M-1)</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>Other member’s thread-owned sockets that connect to this member (1 in and 1 out for each). Note that this might include server threads if any of the other members are servers (see Server).</p></td>
 <td><p>Summation over (M-1) other members of (T*2)</p></td>
 </tr>
@@ -136,21 +136,21 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>Listener for incoming client connections</td>
 <td><p>1</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>Client pool connections to server</td>
 <td>Number of pool connections to this server</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>Threads servicing client requests (the lesser of the client pool connection count and the server’s <code>max-threads</code> setting). These connections are to the server’s peers.</p></td>
 <td><p>(2 * number of threads in a server that service client pool connections)</p>
 <p>* (M-1)</p>
 <p>These threads do not share sockets.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>Subscription connections</td>
 <td><p>2 * number of client subscription connections to this server</p></td>
 </tr>
@@ -177,11 +177,11 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><p>Pool connection</p></td>
 <td><p>summation over the client pools of max-connections</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>Subscription connections</p></td>
 <td><p>2 * summation over the client pools of subscription-enabled</p></td>
 </tr>
diff --git a/geode-docs/managing/monitor_tune/socket_communication_setting_socket_buffer_sizes.html.md.erb b/geode-docs/managing/monitor_tune/socket_communication_setting_socket_buffer_sizes.html.md.erb
index fa2e277..9f9ca14 100644
--- a/geode-docs/managing/monitor_tune/socket_communication_setting_socket_buffer_sizes.html.md.erb
+++ b/geode-docs/managing/monitor_tune/socket_communication_setting_socket_buffer_sizes.html.md.erb
@@ -43,53 +43,53 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><strong>TCP / IP</strong></td>
 <td>---</td>
 <td>---</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Peer-to-peer send/receive</td>
 <td><p>gemfire.properties</p></td>
 <td>socket-buffer-size</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Client send/receive</td>
 <td><p>cache.xml &lt;pool&gt;</p></td>
 <td>socket-buffer-size</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Server send/receive</td>
 <td><code class="ph codeph">gfsh start server</code> or
 <p>cache.xml &lt;CacheServer&gt;</p></td>
 <td>socket-buffer-size</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>UDP Multicast</strong></td>
 <td>---</td>
 <td>---</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Peer-to-peer send</td>
 <td>gemfire.properties</td>
 <td>mcast-send-buffer-size</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Peer-to-peer receive</td>
 <td>gemfire.properties</td>
 <td>mcast-recv-buffer-size</td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>UDP Unicast</strong></td>
 <td>---</td>
 <td>---</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Peer-to-peer send</td>
 <td>gemfire.properties</td>
 <td>udp-send-buffer-size</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Peer-to-peer receive</td>
 <td>gemfire.properties</td>
 <td>udp-recv-buffer-size</td>
diff --git a/geode-docs/managing/monitor_tune/sockets_and_gateways.html.md.erb b/geode-docs/managing/monitor_tune/sockets_and_gateways.html.md.erb
index bd77797..8e1e587 100644
--- a/geode-docs/managing/monitor_tune/sockets_and_gateways.html.md.erb
+++ b/geode-docs/managing/monitor_tune/sockets_and_gateways.html.md.erb
@@ -32,18 +32,18 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><strong>TCP / IP</strong></td>
 <td>---</td>
 <td>---</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Gateway sender</td>
 <td><code class="ph codeph">gfsh create gateway-sender</code> or
 <p>cache.xml &lt;gateway-sender&gt;</p></td>
 <td>socket&#8209;buffer&#8209;size</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Gateway receiver</td>
 <td><code class="ph codeph">gfsh create gateway-receiver</code> or cache.xml &lt;gateway-receiver&gt;</td>
 <td>socket-buffer-size</td>
@@ -91,15 +91,15 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><p>Listener for incoming connections</p></td>
 <td><p>summation of the number of gateway-receivers defined for the member</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>Incoming connection</p></td>
 <td><p>summation of the total number of remote gateway senders configured to connect to the gateway receiver</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>Outgoing connection</p></td>
 <td><p>summation of the number of gateway senders defined for the member</p></td>
 </tr>
diff --git a/geode-docs/reference/statistics_list.html.md.erb b/geode-docs/reference/statistics_list.html.md.erb
index 6cc0fe9..24e17f7 100644
--- a/geode-docs/reference/statistics_list.html.md.erb
+++ b/geode-docs/reference/statistics_list.html.md.erb
@@ -1347,7 +1347,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">actualRedundantCopies</code></td>
 <td>The least current redundant number of copies for any data in this partitioned region (there may be some data that is fully redundant, but some data will have only this number of copies). This value may drop when a data store is lost or rise when a data store is added. This value may drop temporarily during partitioned region creation or destruction and then rise again.
 <div class="note note">
@@ -1356,11 +1356,11 @@
 </div>
 A healthy partitioned region will maintain a value equal to configuredRedundantCopies. The user should add one or more data stores if the value remains low. High-availability may result in a brief fluctuation, but it should return to a value equal to configuredRedundantCopies if there are sufficient data stores present (that is, killing one data store will cause its data to fail over to another data store).</td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">configuredRedundantCopies</code></td>
 <td>This is equivalent to the PartitionAttributes.getRedundantCopies configuration that was used to create this partitioned region. This value remains unchanged for a given partitioned region.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">lowRedundancyBucketCount</code></td>
 <td>The number of buckets in this partitioned region that currently have fewer copies than the configuredRedundantCopies. This value may rise above zero when a data store is lost and return to zero when one or more data stores are added. This value may rise temporarily during partitioned region creation or destruction and then return to zero.
 <div class="note note">
diff --git a/geode-docs/reference/topics/cache_xml.html.md.erb b/geode-docs/reference/topics/cache_xml.html.md.erb
index c41e154..f5c74de 100644
--- a/geode-docs/reference/topics/cache_xml.html.md.erb
+++ b/geode-docs/reference/topics/cache_xml.html.md.erb
@@ -41,32 +41,32 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>copy-on-read</td>
 <td><p>Boolean indicating whether entry value retrieval methods return direct references to the entry value objects in the cache (false) or copies of the objects (true).</p></td>
 <td>False</td>
 </tr>
-<tr class="even">
+<tr>
 <td>is-server</td>
 <td><p>Boolean indicating whether this member is a cache server.</p></td>
 <td>False</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>lock-timeout</td>
 <td><p>The timeout, in seconds, for implicit object lock requests. This setting affects automatic locking only, and does not apply to manual locking. If a lock request does not return before the specified timeout period, it is cancelled and returns with a failure.</p></td>
 <td>60</td>
 </tr>
-<tr class="even">
+<tr>
 <td>lock-lease</td>
 <td><p>The timeout, in seconds, for implicit and explicit object lock leases. This affects both automatic locking and manual locking. Once a lock is obtained, it can remain in force for the lock lease time period before being automatically cleared by the system.</p></td>
 <td>120</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>message-sync-interval</td>
 <td><p>Used for client subscription queue synchronization when this member acts as a server to clients and server redundancy is used. Sets the frequency (in seconds) at which the primary server sends messages to its secondary servers to remove queued events that have already been processed by the clients.</p></td>
 <td>1</td>
 </tr>
-<tr class="even">
+<tr>
 <td>search-timeout</td>
 <td><p>How many seconds a <code class="ph codeph">netSearch</code> operation can wait for data before timing out. You may want to change this based on your knowledge of the network load or other factors.</p></td>
 <td>300</td>
@@ -209,17 +209,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>parallel</td>
 <td>Value of &quot;true&quot; or &quot;false&quot; that specifies the type of gateway sender that <%=vars.product_name%> creates.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>dispatcher-threads</td>
 <td>Number of dispatcher threads that are used to process region events from a gateway sender queue or asynchronous event queue.</td>
 <td>5</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>order-policy</td>
 <td>When the <code class="ph codeph">dispatcher-threads</code> attribute is greater than 1, <code class="ph codeph">order-policy</code> configures the way in which multiple dispatcher threads process region events from a serial gateway queue or serial asynchronous event queue. This attribute can have one of the following values:
 <ul>
@@ -230,67 +230,67 @@
 <p>You cannot configure the <code class="ph codeph">order-policy</code> for a parallel event queue, because parallel queues cannot preserve event ordering for regions. Only the ordering of events for a given partition (or in a given queue of a distributed region) can be preserved.</p></td>
 <td>key</td>
 </tr>
-<tr class="even">
+<tr>
 <td>id</td>
 <td>Unique identifier for the gateway sender, usually an identifier associated with a physical location. This attribute is required.</td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>remote-distributed-system-id</td>
 <td>Integer that uniquely identifies the remote <%=vars.product_name%> cluster to which this gateway sender will send region events. This value corresponds to the <code class="ph codeph">distributed-system-id</code> property specified in locators for the remote cluster. This attribute is required.</td>
 <td>null</td>
 </tr>
-<tr class="even">
+<tr>
 <td>manual-start</td>
 <td><b>Deprecated.</b> Boolean value that specifies whether you need to manually start the gateway sender. If you supply a null value, the default value of false is used, and the gateway sender attempts to start automatically. <em>A manual start is likely to cause data loss, so manual start should never be used in a production system.</em></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>socket-buffer-size</td>
 <td>Size of the socket buffer that sends messages to remote sites. This size should match the size of the <code class="ph codeph">socket-buffer-size</code> attribute of remote gateway receivers that process region events.</td>
 <td>32768</td>
 </tr>
-<tr class="even">
+<tr>
 <td>socket-read-timeout</td>
 <td>Amount of time in milliseconds that the gateway sender will wait to receive an acknowledgment from a remote site. By default this is set to 0, which means there is no timeout. If you do set this timeout, you must set it to a minimum of 30000 (milliseconds). Setting it to a lower number will generate an error message and reset the value to the default of 0.</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-batch-conflation</td>
 <td>Boolean value that determines whether <%=vars.product_name%> should conflate messages.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>batch-size</td>
 <td>Maximum number of messages that a batch can contain.</td>
 <td>100</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>batch-time-interval</td>
 <td>Maximum number of milliseconds that can elapse between sending batches.</td>
 <td>1000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>enable-persistence</td>
 <td>Boolean value that determines whether <%=vars.product_name%> persists the gateway queue.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disk-store-name</td>
 <td>Named disk store to use for storing the queue overflow, or for persisting the queue. If you specify a value, the named disk store must exist. If you specify a null value, <%=vars.product_name%> uses the default disk store for overflow and queue persistence.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>disk-synchronous</td>
 <td>For regions that write to disk, boolean that specifies whether disk writes are done synchronously for the region.</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>maximum-queue-memory</td>
 <td>Maximum amount of memory in megabytes that the queue can consume before overflowing to disk.</td>
 <td>100 MB</td>
 </tr>
-<tr class="even">
+<tr>
 <td>alert-threshold</td>
 <td>Maximum number of milliseconds that a region event can remain in the gateway sender queue before <%=vars.product_name%> logs an alert.</td>
 <td>0</td>
@@ -400,39 +400,39 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>start-port</td>
 <td><p>Starting port number to use when specifying the range of possible port numbers this gateway receiver will use to connects to gateway senders in other sites. <%=vars.product_name%> chooses an unused port number in the specified port number range to start the receiver. If no port numbers in the range are available, an exception is thrown.</p>
 <p>The <code class="ph codeph">STARTPORT</code> value is inclusive while the <code class="ph codeph">ENDPORT</code> value is exclusive. For example, if you specify <code class="ph codeph">STARTPORT=&quot;50510&quot;</code> and <code class="ph codeph">ENDPOINT=&quot;50520&quot;</code>, <%=vars.product_name%> chooses a port value from 50510 to 50519.</p></td>
 <td>5000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>end-port</td>
 <td><p>Defines the upper bound port number to use when specifying the range of possible port numbers this gateway receiver will use to for connections from gateway senders in other sites. <%=vars.product_name%> chooses an unused port number in the specified port number range to start the receiver. If no port numbers in the range are available, an exception is thrown.</p>
 <p>The <code class="ph codeph">ENDPORT</code> value is exclusive while the <code class="ph codeph">STARTPORT</code> value is inclusive. For example, if you specify <code class="ph codeph">STARTPORT=&quot;50510&quot;</code> and <code class="ph codeph">ENDPOINT=&quot;50520&quot;</code>, <%=vars.product_name%> chooses a port value from 50510 to 50519.</p></td>
 <td>5500</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>bind-address</td>
 <td>Network address for connections from gateway senders in other sites. Specify the address as a literal string value.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>hostname-for-senders</td>
 <td>Attribute where you can specify an IP address or hostname for gateway sender connections. If you configure hostname-for-senders, locators will use the provided hostname or IP address when instructing gateway senders on how to connect to gateway receivers. If you provide &quot;&quot; or null as the value, by default the gateway receiver's bind-address will be sent to clients.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>manual-start</td>
 <td>When set to false, the gateway receiver will automatically start when the receiver is created. If set to true, you must manually start the receiver.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>maximum-time-between-pings</td>
 <td>Integer value that specifies the time interval (in milliseconds) to use between pings to connected WAN sites. This value determines the maximum amount of time that can elapse before a remote WAN site is considered offline.</td>
 <td>60000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>socket-buffer-size</td>
 <td>An integer value that sets the buffer size (in bytes) of the socket connection for this gateway receiver. This value should match the <code class="ph codeph">socket-buffer-size</code> setting of gateway senders that connect to this receiver.</td>
 <td>32768</td>
@@ -514,57 +514,57 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>id</td>
 <td>Unique identifier for the queue. This attribute is required.</td>
 <td>null</td>
 </tr>
-<tr class="even">
+<tr>
 <td>parallel</td>
 <td>Value of &quot;true&quot; or &quot;false&quot; that specifies the type of queue that <%=vars.product_name%> creates.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>batch-size</td>
 <td>Maximum number of messages that a batch can contain.</td>
 <td>100</td>
 </tr>
-<tr class="even">
+<tr>
 <td>batch-time-interval</td>
 <td>Maximum number of milliseconds that can elapse between sending batches.</td>
 <td>5</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-batch-conflation</td>
 <td>Boolean value that determines whether <%=vars.product_name%> should conflate messages.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>disk-store-name</td>
 <td>Named disk store to use for storing queue overflow, or for persisting the queue. If you specify a value, the named disk store must exist. If you specify a null value, <%=vars.product_name%> uses the default disk store for overflow and queue persistence.</td>
 <td>null specifies the default disk store</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disk-synchronous</td>
 <td>For regions that write to disk, boolean that specifies whether disk writes are done synchronously for the region.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>dispatcher-threads</td>
 <td>Number of dispatcher threads that are used to process region events from the queue.</td>
 <td>5</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>forward-expiration-destroy</td>
 <td>When true, forwards expiration destroy operations to AsyncEventListener.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>maximum-queue-memory</td>
 <td>Maximum amount of memory in megabytes that the queue can consume before overflowing to disk.</td>
 <td>100 mb</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>order-policy</td>
 <td>When the <code class="ph codeph">dispatcher-threads</code> attribute is greater than 1, <code class="ph codeph">order-policy</code> configures the way in which multiple dispatcher threads process region events from the queue. This attribute can have one of the following values:
 <ul>
@@ -575,12 +575,12 @@
 <p>You cannot configure the <code class="ph codeph">order-policy</code> for a parallel event queue, because parallel queues cannot preserve event ordering for regions. Only the ordering of events for a given partition (or in a given queue of a distributed region) can be preserved.</p></td>
 <td>key</td>
 </tr>
-<tr class="even">
+<tr>
 <td>pause-event-processing</td>
 <td>When true, event dispatching from the queue to the listener(s) will be paused when the AsyncEventQueue is started.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>persistent</td>
 <td>Boolean value that determines whether <%=vars.product_name%> persists this queue.</td>
 <td>False</td>
@@ -665,23 +665,23 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>bind-address</td>
 <td>Hostname or IP address that the server is to listen on for client connections. If null, the server listens on the machine’s default address.</td>
 <td>null</td>
 </tr>
-<tr class="even">
+<tr>
 <td>hostname-for-clients</td>
 <td>Hostname or IP address to pass to the client as the location where the server is listening. When the server connects to the locator it tells the locator the host and port where it is listening for client connections. If the host the server uses by default is one that the client can’t translate into an IP address, the client will have no route to the server’s host and won’t be able to find the server. For this situation, you must supply the server’s alternate hostname for the locator to pass to the client. If null, the server’s <code class="ph codeph">bind-address</code> setting is used.</td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>load-poll-interval</td>
 <td>Frequency, in milliseconds, to poll the load probe for load information on the server.</td>
 <td>5000
 <p>(5 seconds)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>max-connections</td>
 <td>Maximum number of client connections for the server. When the maximum is reached, the server refuses additional client connections.
 <p>
@@ -689,7 +689,7 @@
 Set this at least as high as max-threads.</p></td>
 <td>800</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>max-threads</td>
 <td>Maximum number of threads allowed in this server to service client connections. When the limit is reached, server threads begin servicing multiple connections. A zero setting causes the server to use a thread for every client connection.
 <p>
@@ -697,7 +697,7 @@
 Set this no higher than max-connections.</p></td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>maximum-message-count</td>
 <td>Maximum number of messages allowed in a subscription queue. When the queue reaches this limit, messages block.
 <p>
@@ -705,7 +705,7 @@
 Used only if <code class="ph codeph">client-subscription</code> is not configured.</p></td>
 <td>230000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>maximum-time-between-pings</td>
 <td>Maximum time, in milliseconds, the server allows to pass between messages or pings indicating a client is healthy.
 <p>
@@ -714,7 +714,7 @@
 <td>60000
 <p>(1 minute)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>message-time-to-live</td>
 <td>Setting used for highly available subscription queues. The expiration time, in seconds, for non-durable messages in the secondary server’s client subscription queue. The system removes non-durable messages that have been in the queue beyond this time. If set to 0 (zero), the messages are never removed.
 <p>
@@ -723,17 +723,17 @@
 <td>180
 <p>(3 minutes)</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>port</td>
 <td>Port that the server listens on for client communication.</td>
 <td>40404</td>
 </tr>
-<tr class="even">
+<tr>
 <td>socket-buffer-size</td>
 <td>Size for socket buffers used for server-to-client communication.</td>
 <td>32768</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>tcp-no-delay</td>
 <td>When set to true, enables TCP_NODELAY for <%=vars.product_name%> server connections to clients.</td>
 <td>false</td>
@@ -821,23 +821,23 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>free-connection-timeout</td>
 <td>Amount of time a thread will wait to get a pool connection before timing out with an exception. This timeout keeps threads from waiting indefinitely when the pool’s <code class="ph codeph">max-connections</code> has been reached and all connections in the pool are in use by other threads.</td>
 <td>10000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>idle-timeout</td>
 <td>Maximum time, in milliseconds, a pool connection can stay open without being used when there are more than <code class="ph codeph">min-connections</code> in the pool. Pings over the connection do not count as connection use. If set to -1, there is no idle timeout.</td>
 <td>5000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>load-conditioning-interval</td>
 <td>Amount of time, in milliseconds, a pool connection can remain open before being eligible for silent replacement to a less-loaded server.</td>
 <td>300000
 <p>(5 minutes)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>max-connections</td>
 <td>Maximum number of pool connections the pool can create. If the maximum connections are in use, an operation requiring a client-to-server connection blocks until a connection becomes available or the <code class="ph codeph">free-connection-timeout</code> is reached. If set to -1, there is no maximum. The setting must indicate a cap greater than <code class="ph codeph">min-connections</code>.
 <p>
@@ -845,17 +845,17 @@
 If you need to use this to cap your pool connections, you should disable the pool attribute <code class="ph codeph">pr-single-hop-enabled</code>. Leaving single hop enabled can increase thrashing and lower performance.</p></td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>min-connections</td>
 <td>Minimum number of pool connections to keep available at all times. Used to establish the initial connection pool. If set to 0 (zero), no connection is created until an operation requires it. This number is the starting point, with more connections added later as needed, up to the <code class="ph codeph">max-connection</code> setting. The setting must be an integer greater than or equal to 0.</td>
 <td>1</td>
 </tr>
-<tr class="even">
+<tr>
 <td>multiuser-authentication</td>
 <td>Used for installations with security where you want to accommodate multiple users within a single client. If set to true, the pool provides authorization for multiple user instances in the same client application, and each user accesses the cache through its own <code class="ph codeph">RegionService</code> instance. If false, the client either uses no authorization or just provides credentials for the single client process.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>name</td>
 <td>Name of this pool. Used in the client region pool-name to assign this pool to a region in the client cache.
 <p>
@@ -863,7 +863,7 @@
 This is a required property with no default setting.</p></td>
 <td>none</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ping-interval</td>
 <td>How often to communicate with the server to show the client is alive, set in milliseconds. Pings are only sent when the ping-interval elapses between normal client messages.
 <p>
@@ -871,22 +871,22 @@
 Set this lower than the server’s <code class="ph codeph">maximum-time-between-pings</code>.</p></td>
 <td>10000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>pr-single-hop-enabled</td>
 <td>Setting used to improve access to partitioned region data in the servers. Indicates whether to use metadata about the partitioned region data storage locations to decide where to send some data requests. This allows a client to send a data operation directly to the server hosting the key. Without this, the client contacts any available server and that server contacts the data store. This is used only for operations that can be carried out on a server-by-server basis, like put, get, and destroy.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>read-timeout</td>
 <td>Maximum time, in milliseconds, for the client to wait for a response from a server.</td>
 <td>10000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>retry-attempts</td>
 <td>Number of times to retry a client request before giving up. If one server fails, the pool moves to the next, and so on until it is successful or it hits this limit. If the available servers are fewer than this setting, the pool will retry servers that have already failed until it reaches the limit. If this is set to -1, the pool tries every available server once.</td>
 <td>-1</td>
 </tr>
-<tr class="even">
+<tr>
 <td>server-group</td>
 <td>Logical named server group to use from the pool. A null value uses the global server group to which all servers belong.
 <p>
@@ -894,17 +894,17 @@
 This is only used when the <code class="ph codeph">locator</code> list is defined.</p></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>socket-buffer-size</td>
 <td>Size for socket buffers from the client to the server. Default: 32768.</td>
 <td>32768</td>
 </tr>
-<tr class="even">
+<tr>
 <td>statistic-interval</td>
 <td>Interval, in milliseconds, at which to send client statistics to the server. If set to -1, statistics are not sent.</td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>subscription-ack-interval</td>
 <td>Time, in milliseconds, between messages to the primary server to acknowledge event receipt.
 <p>
@@ -912,19 +912,19 @@
 Used only when <code class="ph codeph">subscription-redundancy</code> is not ‘0’ (zero).</p></td>
 <td>100</td>
 </tr>
-<tr class="even">
+<tr>
 <td>subscription-enabled</td>
 <td>Boolean indicating whether the server should connect back to the client and automatically sends server-side cache update information. Any bind address information for the client is automatically passed to the server for use in the callbacks.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>subscription-message-
 <p>tracking-timeout</p></td>
 <td>Time-to-live, in milliseconds, for entries in the client’s message tracking list.</td>
 <td>900000
 <p>(15 minutes)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>subscription-redundancy</td>
 <td>Number of servers to use as backup to the primary for highly available subscription queue management. If set to 0, none are used. If set to -1, all available servers are used.</td>
 <td>0</td>
@@ -1025,54 +1025,54 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>name</td>
 <td>The name of the Disk Store.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>auto-compact</td>
 <td>Set to true to automatically compact the disk files.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>compaction-threshold</td>
 <td>The threshold at which an oplog will become compactable. Until it reaches this threshold the oplog will not be compacted.
 <p>The threshold is a percentage in the range 0 to 100.</p></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>allow-force-compaction</td>
 <td>Set to true to allow disk compaction to be forced on this disk store.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>max-oplog-size</td>
 <td>The maximum size, in megabytes, of an oplog (operation log) file.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>time-interval</td>
 <td>The number of milliseconds that can elapse before unwritten data is written to disk.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>write-buffer-size</td>
 <td>The size of the write buffer that this disk store uses when writing data to disk. Larger values may increase performance but use more memory. The disk store allocates one direct memory buffer of this size.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>queue-size</td>
 <td>Maximum number of operations that can be asynchronously queued to be written to disk.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disk-usage-warning-percentage</td>
 <td>Disk usage above this threshold generates a warning message. For example, if the threshold is set to 90%, then on a 1 TB drive falling under 100 GB of free disk space generates the warning.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
 <td>90</td>
 </tr>
-<tr class="even">
+<tr>
 <td>disk-usage-critical-percentage</td>
 <td>Disk usage above this threshold generates an error message and shuts down the member's cache. For example, if the threshold is set to 99%, then falling under 10 GB of free disk space on a 1 TB drive generates the error and shuts down the cache.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
@@ -1119,7 +1119,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>dir-size</td>
 <td>Maximum amount of space to use for the disk store, in megabytes.</td>
 <td>214748364
@@ -1213,7 +1213,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>concurrency-level</td>
 <td>Gives an estimate of the maximum number of application threads that will concurrently access a region entry at one time. This attribute does not apply to partitioned regions. This attribute helps <%=vars.product_name%> optimize the use of system resources and reduce thread contention. This sets an initial parameter on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries.
 <p>
@@ -1226,7 +1226,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>16 (threads)</td>
 </tr>
-<tr class="even">
+<tr>
 <td>data-policy</td>
 <td><p>Specifies how the local cache handles data for a region. This setting controls behavior such as local data storage and region initialization.</p>
 <p>
@@ -1236,31 +1236,31 @@
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>empty</td>
 <td>No data storage in the local cache. The region always appears empty. Use this for event delivery to and from the local cache without the memory overhead of data storage - zero-footprint producers that only distribute data to others and zero-footprint consumers that only see events. To receive events with this, set the region's <code class="ph codeph">subscription-attributes</code> <code class="ph codeph">interest-policy</code> to all.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>normal</td>
 <td>Data used locally (accessed with <code class="ph codeph">get</code>, stored with <code class="ph codeph">put</code>, etc.) is stored in the local cache. This policy allows the contents in the cache to differ from other caches.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>partition</td>
 <td>Data is partitioned across local and remote caches using the automatic data distribution behavior of partitioned regions. Additional configuration is done in the <code class="ph codeph">partition-attributes</code>.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>replicate</td>
 <td>The region is initialized with the data from other caches. After initialization, all events for the distributed region are automatically copied into the local region, maintaining a replica of the entire distributed region in the local cache. Operations that would cause the contents to differ with other caches are not allowed. This is compatible with local <code class="ph codeph">scope</code>, behaving the same as for normal.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>persistent-partition</td>
 <td>Behaves the same as <code class="ph codeph">partition</code> and also persists data to disk.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>persistent-replicate</td>
 <td>Behaves the same as <code class="ph codeph">replicate</code> and also persists data to disk.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>preloaded</td>
 <td>Initializes like a replicated region, then, once initialized, behaves like a normal region.</td>
 </tr>
@@ -1279,7 +1279,7 @@
 <p>If you use <code class="ph codeph">data-policy</code>, you must set the scope explicitly.</p></td>
 <td>normal</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-async-conflation</td>
 <td><p>For TCP/IP distributions between peers, specifies whether to allow aggregation of asynchronous messages sent by the producer member for the region. This is a special-purpose voolean attribute that applies only when asynchronous queues are used for slow consumers. A false value disables conflation so that all asynchronous messages are sent individually. This special-purpose attribute gives you extra control over peer-to-peer communication between distributed regions using TCP/IP. This attribute does not apply to client/server communication or to communication using the UDP unicast or IP multicast protocols.</p>
 <p>
@@ -1292,7 +1292,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-subscription-conflation</td>
 <td><p>Boolean for server regions that specifies whether the server can conflate its messages to the client. A true value enables conflation.</p>
 <p>
@@ -1305,7 +1305,7 @@
  &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>gateway-sender-ids</td>
 <td><p>Specifies one or more gateway sender IDs to use for distributing region events to remote <%=vars.product_name%> sites. Specify multiple IDs as a comma-separated list.</p>
 <p><strong>API:</strong> <code class="ph codeph">addGatewaySenderId</code></p>
@@ -1315,7 +1315,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>async-event-queue-ids</td>
 <td>Specifies one or more asynchronous event queues to use for distributing region events an <code class="ph codeph">AsyncEventListener</code> implementation (for example, for write-behind cache event handling). Specify multiple IDs as a comma-separated list.
 <p><strong>API</strong>: <code class="ph codeph">addAsyncEventQueueId</code></p>
@@ -1325,13 +1325,13 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>hub-id</td>
 <td><p>If the <code class="ph codeph">enable-gateway</code> attribute is set to true, a comma-separated list of gateway hub IDs that receive events from the region.</p>
 <p>Used only with GemFire version 6.x gateway configurations. For GemFire 7.0 configuration, see the <code class="ph codeph">gateway-sender-id</code> attribute of the <code class="ph codeph">&lt;region-attributes&gt;</code> element.</p></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>id</td>
 <td><p>Stores the region attribute settings in the cache with this identifier. Once stored, the attributes can be retrieved using the region attribute <code class="ph codeph">refid</code>.</p>
 <p><strong>API:</strong> <code class="ph codeph">setId</code></p>
@@ -1341,7 +1341,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ignore-jta</td>
 <td><p>Boolean that determines whether operations on this region participate in active JTA transactions or ignore them and operate outside of the transactions. This is primarily used in cache loaders, writers, and listeners that need to perform non-transactional operations on a region, such as caching a result set.</p>
 <p><strong>API:</strong> <code class="ph codeph">setIgnoreJTA</code></p>
@@ -1351,7 +1351,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>index-update-type</td>
 <td><p>Specifies whether region indexes are maintained synchronously with region modifications, or asynchronously in a background thread. In the <code class="ph codeph">cache.xml</code> file, this is set as a value, asynchronous or synchronous, assigned to the <code class="ph codeph">index-update-type</code> region attribute. Set this through the API by passing a boolean to the <code class="ph codeph">setIndexMaintenanceSynchronous</code> method.</p>
 <p><strong>API:</strong> <code class="ph codeph">setIndexMaintenanceSynchronous</code></p>
@@ -1361,7 +1361,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>synchronous updates</td>
 </tr>
-<tr class="even">
+<tr>
 <td>initial-capacity</td>
 <td><p>Together with the <code class="ph codeph">load-factor</code> region attribute, sets the initial parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries.</p>
 <p><strong>API:</strong> <code class="ph codeph">setInitialCapacity</code></p>
@@ -1371,7 +1371,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>16</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>is-lock-grantor</td>
 <td><p>Determines whether this member defines itself as the lock grantor for the region at region creation time. This only specifies whether the member becomes lock grantor at creation and does not reflect the current state of the member’s lock grantor status. The member’s lock grantor status may change if another member subsequently defines the region with <code class="ph codeph">is-lock-grantor</code> set to true. This attribute is only relevant for regions with <code class="ph codeph">global</code> <code class="ph codeph">scope</code>, as only they allow locking. It affects implicit and explicit locking.</p>
 <p><strong>API:</strong> <code class="ph codeph">setLockGrantor</code></p>
@@ -1381,7 +1381,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>load-factor</td>
 <td><p>Together with the initial-capacity region attribute, sets the initial parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries. This must be a floating point number between 0 and 1, inclusive.</p>
 <p>
@@ -1394,12 +1394,12 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>.75</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>mirror-type</td>
 <td>Deprecated</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>multicast-enabled</td>
 <td><p>Boolean that specifies whether distributed operations on a region should use multicasting. To enable this, multicast must be enabled for the cluster with the <code class="ph codeph">mcast-port</code> <code class="ph codeph">gemfire.properties</code> setting.</p>
 <p><strong>API:</strong> <code class="ph codeph">setMulticastEnabled</code></p>
@@ -1409,7 +1409,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>pool-name</td>
 <td><p>Identifies the region as a client region and specifies the server pool the region is to use. The named pool must be defined in the client cache before the region is created. If this is not set, the region does not connect to the servers as a client region.</p>
 <p><strong>API:</strong> <code class="ph codeph">setPoolName</code></p>
@@ -1444,7 +1444,7 @@
 &lt;/client-cache&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>disk-store-name</td>
 <td><p>Assigns the region to the disk store with this name from the disk stores defined for the cache. Persist region data to disk by defining the region as persistent using the Shortcut Attribute Options or data-policy settings. Overflow data to disk by implementing LRU eviction-attributes with an action of overflow to disk. Each disk store defines the file system directories to use, how data is written to disk, and other disk storage maintenance properties. In addition, the <code class="ph codeph">disk-synchronous</code> region attribute specifies whether writes are done synchronously or asynchronously.</p>
 <p><strong>API:</strong> <code class="ph codeph">setDiskStoreName</code></p>
@@ -1454,7 +1454,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disk-synchronous</td>
 <td><p>For regions that write to disk, boolean that specifies whether disk writes are done synchronously for the region.</p>
 <p><strong>API:</strong> <code class="ph codeph">setDiskSynchronous</code></p>
@@ -1465,7 +1465,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>refid</td>
 <td><p>Retrieves region shortcuts and user-defined named region attributes for attributes initialization</p>
 <p><strong>API:</strong> <code class="ph codeph">setRefId</code></p>
@@ -1478,7 +1478,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>scope</td>
 <td><p>Definition: Determines how updates to region entries are distributed to the other caches in the cluster where the region and entry are defined. Scope also determines whether to allow remote invocation of some of the region’s event handlers, and whether to use region entry versions to provide consistent updates across replicated regions.</p>
 <p>
@@ -1491,19 +1491,19 @@
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local</td>
 <td>No distribution. The region is visible only to threads running inside the member.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>distributed-no-ack</td>
 <td>Events are distributed to remote caches with no acknowledgement required.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>distributed-ack</td>
 <td>Events are distributed to remote caches with receipt acknowledgement required. Region entry versions are used to provide consistent updates across members of the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>global</td>
 <td>Events are distributed to remote caches with global locking to ensure distributed cache consistency.</td>
 </tr>
@@ -1517,7 +1517,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>distributed-no-ack</td>
 </tr>
-<tr class="even">
+<tr>
 <td>statistics-enabled</td>
 <td>Boolean specifying whether to gather statistics on the region. Must be true to use expiration on the region. <%=vars.product_name%> provides a standard set of statistics for cached regions and region entries, which give you information for fine-tuning your cluster. Unlike other <%=vars.product_name%> statistics, statistics for local and distributed regions are not archived and cannot be charted. They are kept in instances of <code class="ph codeph">org.apache.geode.cache.CacheStatistics</code> and made available through the region and its entries through the <code class="ph codeph">Region.getStatistics</code> and <code class="ph codeph">Region.Entry.getStatistics</code> methods.
 <p><strong>API:</strong> <code class="ph codeph">setStatisticsEnabled</code></p>
@@ -1527,7 +1527,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>cloning-enabled</td>
 <td><p>Determines how <code class="ph codeph">fromDelta</code> applies deltas to the local cache for delta propagation. When true, the updates are applied to a clone of the value and then the clone is saved to the cache. When false, the value is modified in place in the cache.</p>
 <p><strong>API:</strong> <code class="ph codeph">setCloningEnabled</code></p>
@@ -1537,7 +1537,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>concurrency-checks-enabled</td>
 <td><p>Determines whether members perform checks to provide consistent handling for concurrent or out-of-order updates to distributed regions. See [Consistency for Region Updates](../../developing/distributed_regions/region_entry_versions.html#topic_CF2798D3E12647F182C2CEC4A46E2045).</p>
 <p>
@@ -1550,7 +1550,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>off-heap</td>
 <td><p>Specifies that the region uses off-heap memory to store entry values, including values for region entries and queue entries. The region will still use heap memory for everything else, such as entry keys and the ConcurrentHashMap.</p>
 <p><strong>API:</strong> <code class="ph codeph">setOffHeap</code></p>
@@ -1648,31 +1648,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -1767,31 +1767,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -1884,31 +1884,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -2003,31 +2003,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -2217,25 +2217,25 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>loss-action</td>
 <td><p>Set one of the following values to specify how access to the region is affected when one or more required roles are lost.</p>
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>full-access</td>
 <td>Access to the region is unaffected when required roles are missing.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>limited-access</td>
 <td>Only local access to the region is allowed when required roles are missing.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>no-access</td>
 <td>The region is unavailable when required roles are missing.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>reconnect</td>
 <td>Loss of required roles causes the entire cache to be closed.</td>
 </tr>
@@ -2244,17 +2244,17 @@
 </div></td>
 <td>no_access</td>
 </tr>
-<tr class="even">
+<tr>
 <td>resumption-action</td>
 <td><div class="p">
 Specifies how the region is affected by resumption of reliability when one or more missing required roles return to the distributed membership. Set one of the following values:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>none</td>
 <td>No special action takes place when reliability resumes.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>reinitialize</td>
 <td>Resumption of reliability causes the region to be cleared of all data and replicated regions will do a new getInitialImage operation to repopulate the region.</td>
 </tr>
@@ -2329,17 +2329,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>interest-policy</td>
 <td>The two <code class="ph codeph">interest-policy</code> options are:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>cache-content</td>
 <td>The default, registers interest in events only for entries that are already in the local region. For partitioned regions, the local member must hold the primary copy of the entry’s data.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>all</td>
 <td>Registers interest in events for all entries that are anywhere in the distributed or partitioned region, regardless of whether they are already present in the local cache.</td>
 </tr>
@@ -2471,13 +2471,13 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>action</td>
 <td>Set one of the following eviction actions:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-destroy</td>
 <td>Removes the entry from the local cache, but does not distribute the removal operation to remote
 members.  This action can be applied to an entry in a partitioned region, but is not recommended
@@ -2485,7 +2485,7 @@
 redundant buckets.  When applied to an entry in a replicated region, <%=vars.product_name%> silently changes
 the region type to "preloaded" to accommodate the local modification.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>overflow-to-disk</td>
 <td>The entry's value is overflowed to disk and set to null in memory. The
 entry's key is retained in the cache.</td>
@@ -2495,7 +2495,7 @@
 </div></td>
 <td>local-destroy</td>
 </tr>
-<tr class="even">
+<tr>
 <td>maximum</td>
 <td>The maximum number of entries allowed in a region.</td>
 <td> </td>
@@ -2528,13 +2528,13 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>action</td>
 <td>Set one of the following eviction actions:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-destroy</td>
 <td>Removes the entry from the local cache, but does not distribute the removal operation to remote
 members.  This action can be applied to an entry in a partitioned region, but is not recommended
@@ -2542,7 +2542,7 @@
 redundant buckets.  When applied to an entry in a replicated region, <%=vars.product_name%> silently changes
 the region type to "preloaded" to accommodate the local modification.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>overflow-to-disk</td>
 <td>The entry's value is overflowed to disk and set to null in memory. The
 entry's key is retained in the cache.</td>
@@ -2577,13 +2577,13 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>action</td>
 <td>Set one of the following eviction actions:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-destroy</td>
 <td>Removes the entry from the local cache, but does not distribute the removal operation to remote
 members.  This action can be applied to an entry in a partitioned region, but is not recommended
@@ -2591,7 +2591,7 @@
 redundant buckets.  When applied to an entry in a replicated region, <%=vars.product_name%> silently changes
 the region type to "preloaded" to accommodate the local modification.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>overflow-to-disk</td>
 <td>The entry's value is overflowed to disk and set to null in memory. The
 entry's key is retained in the cache.</td>
@@ -2601,7 +2601,7 @@
 </div></td>
 <td>local-destroy</td>
 </tr>
-<tr class="even">
+<tr>
 <td>maximum</td>
 <td>The maximum amount of memory used in the region, in megabytes.</td>
 <td> </td>
@@ -2669,17 +2669,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>blocking-timeout-seconds</td>
 <td>The number of seconds that a connection remains associated with a transaction. If this value is exceeded, the connection is disassociated from the transaction.</td>
 <td>120</td>
 </tr>
-<tr class="even">
+<tr>
 <td>conn-pooled-datasource-class</td>
 <td>Java class used for the <code class="ph codeph">PooledDataSource</code> type.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>connection-url</td>
 <td>URL for connecting to the datasource.
 <p>
@@ -2687,27 +2687,27 @@
 <p>If you are connecting to a JCA data source driver that implements XA transactions (where the jndi-binding type is <strong>XAPooledDataSource</strong>), do not use this attribute. Instead, define configuration properties for your database. See <a href="#config-property">&lt;config-property&gt</a> for an example.</p></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>idle-timeout-seconds</td>
 <td>The maximum number of seconds that a connection can remain idle in a pool. When this threshold is reached, the connection is removed.</td>
 <td>600</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>init-pool-size</td>
 <td>The initial pool size of a PooledConnection (an XAConnection or a non-XAConnection).</td>
 <td>10</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jdbc-driver-class</td>
 <td>Java class used for the <code class="ph codeph">SimpleDataSource</code> type.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jndi-name</td>
 <td>The <code class="ph codeph">jndi-name</code> attribute is the key binding parameter. If the value of jndi-name is a DataSource, it is bound as java:/myDatabase, where myDatabase is the name you assign to your data source. If the data source cannot be bound to JNDI at runtime, <%=vars.product_name%> logs a warning.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>login-timeout-seconds</td>
 <td><p>The maximum number of seconds for which a thread seeking a connection from a connection pool may be blocked. If the thread is unable to obtain connection in the stipulated time, a <span class="keyword apiname">PoolException</span> is thrown</p>
 <p>If a connection is available the thread returns immediately.</p>
@@ -2715,36 +2715,36 @@
 <p>If a connection is not available, the thread blocks for the specified time while waiting for an available connection.</p></td>
 <td>30</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>managed-conn-factory-class</td>
 <td>If the Resource Adapter is of type <span class="keyword apiname">ManagedDataSource</span>, this class becomes the source of the <span class="keyword apiname">PooledConnection</span>. (This class interface complies with the J2CA Java 2 Connector Architecture.)</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>max-pool-size</td>
 <td>The maximum size of the PooledConnection.</td>
 <td>30</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>password</td>
 <td>Password to access the datasource.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>transaction-type</td>
 <td>When the <code class="ph codeph">type</code> attribute is set to <code class="ph codeph">ManagedDataSource</code>, specifies the type of transaction. Set one of the following <code class="ph codeph">transaction-type</code>s:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>XATransaction</td>
 <td>Select this option when you want to use a<span class="keyword apiname">ManagedConnection</span> interface with a Java Transaction Manager to define transaction boundries. This option allows a <span class="keyword apiname">ManagedDataSource</span> to participate in a transaction with a <%=vars.product_name%> cache.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>NoTransaction</td>
 <td>No transactional behavior is used.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>LocalTransaction</td>
 <td>Select this option when using a <span class="keyword apiname">ManagedDataSource</span> that is not managed by the Java Transaction manager.</td>
 </tr>
@@ -2753,25 +2753,25 @@
 </div></td>
 <td>none</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>type</td>
 <td><div class="p">
 Set one of the following types:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>XAPooledDataSource</td>
 <td>Pooled SQL connections. For this type, you must also set the <code class="ph codeph">xa-datasource-class</code> attribute.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ManagedDataSource</td>
 <td>JNDI binding type for the J2EE Connector Architecture (JCA). ManagedConnectionFactory. For information on the ManagedConnection interface, See the [Oracle ManagedConnection docs](http://docs.oracle.com/javaee/6/api/javax/resource/spi/ManagedConnection.html).</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>PooledDataSource</td>
 <td>Pooled SQL connections. For this type, you must also set the <code class="ph codeph">conn-pooled-datasource-class</code> attribute.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>SimpleDataSource</td>
 <td>Single SQL connection. No pooling of SQL connections is done. Connections are generated on the fly and cannot be reused. For this type, you must also set the <code class="ph codeph">jdbc-driver-class</code> attribute.</td>
 </tr>
@@ -2780,12 +2780,12 @@
 </div></td>
 <td>none</td>
 </tr>
-<tr class="even">
+<tr>
 <td>user-name</td>
 <td>User name to access to the datasource.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>xa-datasource-class</td>
 <td>Java class used for the <code class="ph codeph">XAPooledDataSource</code> type.</td>
 <td> </td>
@@ -3141,13 +3141,13 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>critical-heap-percentage</td>
 <td>Percentage of heap at or above which the cache is considered in danger of becoming inoperable due to garbage collection pauses or out of memory exceptions.
 <p>Only one change to this attribute or critical heap percentage will be allowed at any given time and its effect will be fully realized before the next change is allowed. This feature requires additional VM flags to perform properly. See <code class="ph codeph">setCriticalHeapPercentage()</code> for details.</p></td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-heap-percentage</td>
 <td><p>Set the percentage of heap at or above which the eviction should begin on regions configured for HeapLRU eviction.</p>
 <p>Changing this value may cause eviction to begin immediately.</p>
@@ -3159,12 +3159,12 @@
 </td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>critical-off-heap-percentage</td>
 <td>Percentage of off-heap memory at or above which the cache is considered in danger of becoming inoperable due to garbage collection pauses or out of memory exceptions.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-off-heap-percentage</td>
 <td>Set the percentage of off-heap memory at or above which the eviction should begin on Regions configured for HeapLRU eviction.
 <ul>
diff --git a/geode-docs/reference/topics/client-cache.html.md.erb b/geode-docs/reference/topics/client-cache.html.md.erb
index 10c53fb..65650f9 100644
--- a/geode-docs/reference/topics/client-cache.html.md.erb
+++ b/geode-docs/reference/topics/client-cache.html.md.erb
@@ -41,7 +41,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>copy-on-read</td>
 <td><p>Boolean indicating whether entry value retrieval methods return direct references to the entry value objects in the cache (false) or copies of the objects (true).</p></td>
 <td>False</td>
@@ -134,23 +134,23 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>free-connection-timeout</td>
 <td>Amount of time a thread will wait to get a pool connection before timing out with an exception. This timeout keeps threads from waiting indefinitely when the pool’s <code class="ph codeph">max-connections</code> has been reached and all connections in the pool are in use by other threads.</td>
 <td>10000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>idle-timeout</td>
 <td>Maximum time, in milliseconds, a pool connection can stay open without being used when there are more than <code class="ph codeph">min-connections</code> in the pool. Pings over the connection do not count as connection use. If set to -1, there is no idle timeout.</td>
 <td>5000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>load-conditioning-interval</td>
 <td>Amount of time, in milliseconds, a pool connection can remain open before being eligible for silent replacement to a less-loaded server.</td>
 <td>300000
 <p>(5 minutes)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>max-connections</td>
 <td>Maximum number of pool connections the pool can create. If the maximum connections are in use, an operation requiring a client-to-server connection blocks until a connection becomes available or the <code class="ph codeph">free-connection-timeout</code> is reached. If set to -1, there is no maximum. The setting must indicate a cap greater than <code class="ph codeph">min-connections</code>.
 <div class="note note">
@@ -159,17 +159,17 @@
 </div></td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>min-connections</td>
 <td>Minimum number of pool connections to keep available at all times. Used to establish the initial connection pool. If set to 0 (zero), no connection is created until an operation requires it. This number is the starting point, with more connections added later as needed, up to the <code class="ph codeph">max-connection</code> setting. The setting must be an integer greater than or equal to 0.</td>
 <td>1</td>
 </tr>
-<tr class="even">
+<tr>
 <td>multiuser-authentication</td>
 <td>Used for installations with security where you want to accommodate multiple users within a single client. If set to true, the pool provides authorization for multiple user instances in the same client application, and each user accesses the cache through its own <code class="ph codeph">RegionService</code> instance. If false, the client either uses no authorization or just provides credentials for the single client process.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>name</td>
 <td>Name of this pool. Used in the client region pool-name to assign this pool to a region in the client cache.
 <div class="note note">
@@ -178,7 +178,7 @@
 </div></td>
 <td>none</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ping-interval</td>
 <td>How often to communicate with the server to show the client is alive, set in milliseconds. Pings are only sent when the ping-interval elapses between normal client messages.
 <div class="note note">
@@ -187,22 +187,22 @@
 </div></td>
 <td>10000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>pr-single-hop-enabled</td>
 <td>Setting used to improve access to partitioned region data in the servers. Indicates whether to use metadata about the partitioned region data storage locations to decide where to send some data requests. This allows a client to send a data operation directly to the server hosting the key. Without this, the client contacts any available server and that server contacts the data store. This is used only for operations that can be carried out on a server-by-server basis, like put, get, and destroy.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>read-timeout</td>
 <td>Maximum time, in milliseconds, for the client to wait for a response from a server.</td>
 <td>10000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>retry-attempts</td>
 <td>Number of times to retry a client request before giving up. If one server fails, the pool moves to the next, and so on until it is successful or it hits this limit. If the available servers are fewer than this setting, the pool will retry servers that have already failed until it reaches the limit. If this is set to -1, the pool tries every available server once.</td>
 <td>-1</td>
 </tr>
-<tr class="even">
+<tr>
 <td>server-group</td>
 <td>Logical named server group to use from the pool. A null value uses the global server group to which all servers belong.
 <div class="note note">
@@ -211,23 +211,23 @@
 </div></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>socket-buffer-size</td>
 <td>Size for socket buffers from the client to the server. Default: 32768.</td>
 <td>32768</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>socket-connect-timeout</td>
 <td>The number of milliseconds to wait before timing out on the client socket connect to a server or locator. A value of zero is interpreted as an infinite timeout. If zero, the connection will block until established or an error occurs.
 </td>
 <td>59000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>statistic-interval</td>
 <td>Interval, in milliseconds, at which to send client statistics to the server. If set to -1, statistics are not sent.</td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>subscription-ack-interval</td>
 <td>Time, in milliseconds, between messages to the primary server to acknowledge event receipt.
 <div class="note note">
@@ -236,24 +236,24 @@
 </div></td>
 <td>100</td>
 </tr>
-<tr class="even">
+<tr>
 <td>subscription-enabled</td>
 <td>Boolean indicating whether the server should connect back to the client and automatically sends server-side cache update information. Any bind address information for the client is automatically passed to the server for use in the callbacks.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>subscription-message-
 <p>tracking-timeout</p></td>
 <td>Time-to-live, in milliseconds, for entries in the client’s message tracking list.</td>
 <td>900000
 <p>(15 minutes)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>subscription-redundancy</td>
 <td>Number of servers to use as backup to the primary for highly available subscription queue management. If set to 0, none are used. If set to -1, all available servers are used.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>subscription-timeout-multiplier</td>
 <td>Number of missing server pings that trigger timeout of a subscription feed.
 
@@ -358,54 +358,54 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>name</td>
 <td>The name of the Disk Store.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>auto-compact</td>
 <td>Set to true to automatically compact the disk files.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>compaction-threshold</td>
 <td>The threshold at which an oplog will become compactable. Until it reaches this threshold the oplog will not be compacted.
 <p>The threshold is a percentage in the range 0 to 100.</p></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>allow-force-compaction</td>
 <td>Set to true to allow disk compaction to be forced on this disk store.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>max-oplog-size</td>
 <td>The maximum size, in megabytes, of an oplog (operation log) file.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>time-interval</td>
 <td>The number of milliseconds that can elapse before unwritten data is written to disk.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>write-buffer-size</td>
 <td>The size of the write buffer that this disk store uses when writing data to disk. Larger values may increase performance but use more memory. The disk store allocates one direct memory buffer of this size.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>queue-size</td>
 <td>Maximum number of operations that can be asynchronously queued to be written to disk.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disk-usage-warning-percentage</td>
 <td>Disk usage above this threshold generates a warning message. For example, if the threshold is set to 90%, then on a 1 TB drive falling under 100 GB of free disk space generates the warning.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
 <td>90</td>
 </tr>
-<tr class="even">
+<tr>
 <td>disk-usage-critical-percentage</td>
 <td>Disk usage above this threshold generates an error message and shuts down the member's cache. For example, if the threshold is set to 99%, then falling under 10 GB of free disk space on a 1 TB drive generates the error and shuts down the cache.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
@@ -452,7 +452,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>dir-size</td>
 <td>Maximum amount of space to use for the disk store, in megabytes.</td>
 <td>214748364
@@ -544,7 +544,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>concurrency-level</td>
 <td>Gives an estimate of the maximum number of application threads that will concurrently access a region entry at one time. This attribute does not apply to partitioned regions. This attribute helps <%=vars.product_name%> optimize the use of system resources and reduce thread contention. This sets an initial parameter on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries.
 <div class="note note">
@@ -558,7 +558,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>16 (threads)</td>
 </tr>
-<tr class="even">
+<tr>
 <td>data-policy</td>
 <td><p>Specifies how the local cache handles data for a region. This setting controls behavior such as local data storage and region initialization.</p>
 <div class="note note">
@@ -569,31 +569,31 @@
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>empty</td>
 <td>No data storage in the local cache. The region always appears empty. Use this for event delivery to and from the local cache without the memory overhead of data storage - zero-footprint producers that only distribute data to others and zero-footprint consumers that only see events. To receive events with this, set the region's <code class="ph codeph">subscription-attributes</code> <code class="ph codeph">interest-policy</code> to all.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>normal</td>
 <td>Data used locally (accessed with <code class="ph codeph">get</code>s, stored with <code class="ph codeph">put</code>s, etc.) is stored in the local cache. This policy allows the contents in the cache to differ from other caches.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>partition</td>
 <td>Data is partitioned across local and remote caches using the automatic data distribution behavior of partitioned regions. Additional configuration is done in the <code class="ph codeph">partition-attributes</code>.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>replicate</td>
 <td>The region is initialized with the data from other caches. After initialization, all events for the distributed region are automatically copied into the local region, maintaining a replica of the entire distributed region in the local cache. Operations that would cause the contents to differ with other caches are not allowed. This is compatible with local <code class="ph codeph">scope</code>, behaving the same as for normal.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>persistent-partition</td>
 <td>Behaves the same as <code class="ph codeph">partition</code> and also persists data to disk.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>persistent-replicate</td>
 <td>Behaves the same as <code class="ph codeph">replicate</code> and also persists data to disk.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>preloaded</td>
 <td>Initializes like a replicated region, then, once initialized, behaves like a normal region.</td>
 </tr>
@@ -612,7 +612,7 @@
 <p>If you use <code class="ph codeph">data-policy</code>, you must set the scope explicitly.</p></td>
 <td>normal</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-async-conflation</td>
 <td><p>For TCP/IP distributions between peers, specifies whether to allow aggregation of asynchronous messages sent by the producer member for the region. This is a special-purpose voolean attribute that applies only when asynchronous queues are used for slow consumers. A false value disables conflation so that all asynchronous messages are sent individually. This special-purpose attribute gives you extra control over peer-to-peer communication between distributed regions using TCP/IP. This attribute does not apply to client/server communication or to communication using the UDP unicast or IP multicast protocols.</p>
 <div class="note note">
@@ -626,13 +626,13 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>enable-gateway</td>
 <td><p>Determines whether the gateway is enabled for the region. When set to true, events in the region are sent to the defined gateway hubs.</p>
 Used only with GemFire version 6.x gateway configurations. For GemFire 7.0 configuration, see the <code class="ph codeph">gateway-sender-id</code> attribute of the <code class="ph codeph">&lt;region-attributes&gt;</code> element.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-subscription-conflation</td>
 <td><p>Boolean for server regions that specifies whether the server can conflate its messages to the client. A true value enables conflation.</p>
 <div class="note note">
@@ -646,7 +646,7 @@
  &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>gateway-sender-ids</td>
 <td><p>Specifies one or more gateway sender IDs to use for distributing region events to remote <%=vars.product_name%> sites. Specify multiple IDs as a comma-separated list.</p>
 <p><strong>API:</strong> <code class="ph codeph">addGatewaySenderId</code></p>
@@ -656,7 +656,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>async-event-queue-ids</td>
 <td>Specifies one or more asynchronous event queues to use for distributing region events an <code class="ph codeph">AsyncEventListener</code> implementation (for example, for write-behind cache event handling). Specify multiple IDs as a comma-separated list.
 <p><strong>API</strong>: <code class="ph codeph">addAsyncEventQueueId</code></p>
@@ -666,13 +666,13 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>hub-id</td>
 <td><p>If the <code class="ph codeph">enable-gateway</code> attribute is set to true, a comma-separated list of gateway hub IDs that receive events from the region.</p>
 <p>Used only with GemFire version 6.x gateway configurations. For GemFire 7.0 configuration, see the <code class="ph codeph">gateway-sender-id</code> attribute of the <code class="ph codeph">&lt;region-attributes&gt;</code> element.</p></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>id</td>
 <td><p>Stores the region attribute settings in the cache with this identifier. Once stored, the attributes can be retrieved using the region attribute <code class="ph codeph">refid</code>.</p>
 <p><strong>API:</strong> <code class="ph codeph">setId</code></p>
@@ -682,7 +682,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ignore-jta</td>
 <td><p>Boolean that determines whether operations on this region participate in active JTA transactions or ignore them and operate outside of the transactions. This is primarily used in cache loaders, writers, and listeners that need to perform non-transactional operations on a region, such as caching a result set.</p>
 <p><strong>API:</strong> <code class="ph codeph">setIgnoreJTA</code></p>
@@ -692,7 +692,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>index-update-type</td>
 <td><p>Specifies whether region indexes are maintained synchronously with region modifications, or asynchronously in a background thread. In the <code class="ph codeph">cache.xml</code> file, this is set as a value, asynchronous or synchronous, assigned to the <code class="ph codeph">index-update-type</code> region attribute. Set this through the API by passing a boolean to the <code class="ph codeph">setIndexMaintenanceSynchronous</code> method.</p>
 <p><strong>API:</strong> <code class="ph codeph">setIndexMaintenanceSynchronous</code></p>
@@ -702,7 +702,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>synchronous updates</td>
 </tr>
-<tr class="even">
+<tr>
 <td>initial-capacity</td>
 <td><p>Together with the <code class="ph codeph">load-factor</code> region attribute, sets the initial parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries.</p>
 <p><strong>API:</strong> <code class="ph codeph">setInitialCapacity</code></p>
@@ -712,7 +712,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>16</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>is-lock-grantor</td>
 <td><p>Determines whether this member defines itself as the lock grantor for the region at region creation time. This only specifies whether the member becomes lock grantor at creation and does not reflect the current state of the member’s lock grantor status. The member’s lock grantor status may change if another member subsequently defines the region with <code class="ph codeph">is-lock-grantor</code> set to true. This attribute is only relevant for regions with <code class="ph codeph">global</code> <code class="ph codeph">scope</code>, as only they allow locking. It affects implicit and explicit locking.</p>
 <p><strong>API:</strong> <code class="ph codeph">setLockGrantor</code></p>
@@ -722,7 +722,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>load-factor</td>
 <td><p>Together with the initial-capacity region attribute, sets the initial parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries. This must be a floating point number between 0 and 1, inclusive.</p>
 <div class="note note">
@@ -736,12 +736,12 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>.75</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>mirror-type</td>
 <td>Deprecated</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>multicast-enabled</td>
 <td><p>Boolean that specifies whether distributed operations on a region should use multicasting. To enable this, multicast must be enabled for the cluster with the <code class="ph codeph">mcast-port</code> <code class="ph codeph">gemfire.properties</code> setting.</p>
 <p><strong>API:</strong> <code class="ph codeph">setMulticastEnabled</code></p>
@@ -751,7 +751,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>pool-name</td>
 <td><p>Identifies the region as a client region and specifies the server pool the region is to use. The named pool must be defined in the client cache before the region is created. If this is not set, the region does not connect to the servers as a client region.</p>
 <p><strong>API:</strong> <code class="ph codeph">setPoolName</code></p>
@@ -786,7 +786,7 @@
 &lt;/client-cache&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>disk-store-name</td>
 <td><p>Assigns the region to the disk store with this name from the disk stores defined for the cache. Persist region data to disk by defining the region as persistent using the Shortcut Attribute Options or data-policy settings. Overflow data to disk by implementing LRU eviction-attributes with an action of overflow to disk. Each disk store defines the file system directories to use, how data is written to disk, and other disk storage maintenance properties. In addition, the <code class="ph codeph">disk-synchronous</code> region attribute specifies whether writes are done synchronously or asynchronously.</p>
 <p><strong>API:</strong> <code class="ph codeph">setDiskStoreName</code></p>
@@ -796,7 +796,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disk-synchronous</td>
 <td><p>For regions that write to disk, boolean that specifies whether disk writes are done synchronously for the region.</p>
 <p><strong>API:</strong> <code class="ph codeph">setDiskSynchronous</code></p>
@@ -807,7 +807,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>refid</td>
 <td><p>Retrieves region shortcuts and user-defined named region attributes for attributes initialization</p>
 <p><strong>API:</strong> <code class="ph codeph">setRefId</code></p>
@@ -820,7 +820,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>scope</td>
 <td><p>Definition: Determines how updates to region entries are distributed to the other caches in the cluster where the region and entry are defined. Scope also determines whether to allow remote invocation of some of the region’s event handlers, and whether to use region entry versions to provide consistent updates across replicated regions.</p>
 <div class="note note">
@@ -835,19 +835,19 @@
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local</td>
 <td>No distribution. The region is visible only to threads running inside the member.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>distributed-no-ack</td>
 <td>Events are distributed to remote caches with no acknowledgement required.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>distributed-ack</td>
 <td>Events are distributed to remote caches with receipt acknowledgement required. Region entry versions are used to provide consistent updates across members of the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>global</td>
 <td>Events are distributed to remote caches with global locking to ensure distributed cache consistency.</td>
 </tr>
@@ -861,7 +861,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>distributed-no-ack</td>
 </tr>
-<tr class="even">
+<tr>
 <td>statistics-enabled</td>
 <td>Boolean specifying whether to gather statistics on the region. Must be true to use expiration on the region. <%=vars.product_name%> provides a standard set of statistics for cached regions and region entries, which give you information for fine-tuning your cluster. Unlike other <%=vars.product_name%> statistics, statistics for local and distributed regions are not archived and cannot be charted. They are kept in instances of <code class="ph codeph">org.apache.geode.cache.CacheStatistics</code> and made available through the region and its entries through the <code class="ph codeph">Region.getStatistics</code> and <code class="ph codeph">Region.Entry.getStatistics</code> methods.
 <p><strong>API:</strong> <code class="ph codeph">setStatisticsEnabled</code></p>
@@ -871,7 +871,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>cloning-enabled</td>
 <td><p>Determines how <code class="ph codeph">fromDelta</code> applies deltas to the local cache for delta propagation. When true, the updates are applied to a clone of the value and then the clone is saved to the cache. When false, the value is modified in place in the cache.</p>
 <p><strong>API:</strong> <code class="ph codeph">setCloningEnabled</code></p>
@@ -881,7 +881,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>concurrency-checks-enabled</td>
 <td><p>Determines whether members perform checks to provide consistent handling for concurrent or out-of-order updates to distributed regions. See [Consistency for Region Updates](../../developing/distributed_regions/region_entry_versions.html#topic_CF2798D3E12647F182C2CEC4A46E2045).</p>
 <div class="note note">
@@ -895,7 +895,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>off-heap</td>
 <td><p>Specifies that the region uses off-heap memory to store entry values, including values for region entries and queue entries. The region will still use heap memory for everything else, such as entry keys and the ConcurrentHashMap.</p>
 <p><strong>API:</strong> <code class="ph codeph">setOffHeap</code></p>
@@ -993,31 +993,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -1112,31 +1112,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -1229,31 +1229,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -1348,31 +1348,31 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>timeout</td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>action</td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -1516,17 +1516,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>action</td>
 <td>Set one of the following eviction actions:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-destroy</td>
 <td>Entry is destroyed locally. Not available for replicated regions.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>overflow-to-disk</td>
 <td>Entry is overflowed to disk and the value set to null in memory. For partitioned regions, this provides the most reliable read behavior across the region.</td>
 </tr>
@@ -1535,7 +1535,7 @@
 </div></td>
 <td>local-destroy</td>
 </tr>
-<tr class="even">
+<tr>
 <td>maximum</td>
 <td>The maximum number of entries allowed in a region.</td>
 <td> </td>
@@ -1565,17 +1565,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>action</td>
 <td>Set one of the following eviction actions:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-destroy</td>
 <td>Entry is destroyed locally. Not available for replicated regions.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>overflow-to-disk</td>
 <td>Entry is overflowed to disk and the value set to null in memory. For partitioned regions, this provides the most reliable read behavior across the region.</td>
 </tr>
@@ -1609,17 +1609,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>action</td>
 <td>Set one of the following eviction actions:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-destroy</td>
 <td>Entry is destroyed locally. Not available for replicated regions.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>overflow-to-disk</td>
 <td>Entry is overflowed to disk and the value set to null in memory. For partitioned regions, this provides the most reliable read behavior across the region.</td>
 </tr>
@@ -1628,7 +1628,7 @@
 </div></td>
 <td>local-destroy</td>
 </tr>
-<tr class="even">
+<tr>
 <td>maximum</td>
 <td>The maximum amount of memory used in the region, in megabytes.</td>
 <td> </td>
@@ -1696,17 +1696,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>blocking-timeout-seconds</td>
 <td>The number of seconds that a connection remains associated with a transaction. If this value is exceeded, the connection is disassociated from the transaction.</td>
 <td>120</td>
 </tr>
-<tr class="even">
+<tr>
 <td>conn-pooled-datasource-class</td>
 <td>Java class used for the <code class="ph codeph">PooledDataSource</code> type.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>connection-url</td>
 <td>URL for connecting to the datasource.
 <div class="note note">
@@ -1715,27 +1715,27 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>idle-timeout-seconds</td>
 <td>The maximum number of seconds that a connection can remain idle in a pool. When this threshold is reached, the connection is removed.</td>
 <td>600</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>init-pool-size</td>
 <td>The initial pool size of a PooledConnection (an XAConnection or a non-XAConnection).</td>
 <td>10</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jdbc-driver-class</td>
 <td>Java class used for the <code class="ph codeph">SimpleDataSource</code> type.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jndi-name</td>
 <td>The <code class="ph codeph">jndi-name</code> attribute is the key binding parameter. If the value of jndi-name is a DataSource, it is bound as java:/myDatabase, where myDatabase is the name you assign to your data source. If the data source cannot be bound to JNDI at runtime, <%=vars.product_name%> logs a warning.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>login-timeout-seconds</td>
 <td><p>The maximum number of seconds for which a thread seeking a connection from a connection pool may be blocked. If the thread is unable to obtain connection in the stipulated time, a <span class="keyword apiname">PoolException</span> is thrown</p>
 <p>If a connection is available the thread returns immediately.</p>
@@ -1743,36 +1743,36 @@
 <p>If a connection is not available, the thread blocks for the specified time while waiting for an available connection.</p></td>
 <td>30</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>managed-conn-factory-class</td>
 <td>If the Resource Adapter is of type <span class="keyword apiname">ManagedDataSource</span>, this class becomes the source of the <span class="keyword apiname">PooledConnection</span>. (This class interface complies with the J2CA Java 2 Connector Architecture.)</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>max-pool-size</td>
 <td>The maximum size of the PooledConnection.</td>
 <td>30</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>password</td>
 <td>Password to access the datasource.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>transaction-type</td>
 <td>When the <code class="ph codeph">type</code> attribute is set to <code class="ph codeph">ManagedDataSource</code>, specifies the type of transaction. Set one of the following <code class="ph codeph">transaction-type</code>s:
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>XATransaction</td>
 <td>Select this option when you want to use a<span class="keyword apiname">ManagedConnection</span> interface with a Java Transaction Manager to define transaction boundries. This option allows a <span class="keyword apiname">ManagedDataSource</span> to participate in a transaction with a <%=vars.product_name%> cache.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>NoTransaction</td>
 <td>No transactional behavior is used.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>LocalTransaction</td>
 <td>Select this option when using a <span class="keyword apiname">ManagedDataSource</span> that is not managed by the Java Transaction manager.</td>
 </tr>
@@ -1781,25 +1781,25 @@
 </div></td>
 <td>none</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>type</td>
 <td><div class="p">
 Set one of the following types:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>XAPooledDataSource</td>
 <td>Pooled SQL connections. For this type, you must also set the <code class="ph codeph">xa-datasource-class</code> attribute.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ManagedDataSource</td>
 <td>JNDI binding type for the J2EE Connector Architecture (JCA). ManagedConnectionFactory. For information on the ManagedConnection interface, See: [http://docs.oracle.com/javaee/6/api/javax/resource/spi/ManagedConnection.html](http://docs.oracle.com/javaee/6/api/javax/resource/spi/ManagedConnection.html).</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>PooledDataSource</td>
 <td>Pooled SQL connections. For this type, you must also set the <code class="ph codeph">conn-pooled-datasource-class</code> attribute.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>SimpleDataSource</td>
 <td>Single SQL connection. No pooling of SQL connections is done. Connections are generated on the fly and cannot be reused. For this type, you must also set the <code class="ph codeph">jdbc-driver-class</code> attribute.</td>
 </tr>
@@ -1808,12 +1808,12 @@
 </div></td>
 <td>none</td>
 </tr>
-<tr class="even">
+<tr>
 <td>user-name</td>
 <td>User name to access to the datasource.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td>xa-datasource-class</td>
 <td>Java class used for the <code class="ph codeph">XAPooledDataSource</code> type.</td>
 <td> </td>
@@ -1914,7 +1914,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>concurrency-level</td>
 <td>Gives an estimate of the maximum number of application threads that will concurrently access a region entry at one time. This attribute does not apply to partitioned regions. This attribute helps <%=vars.product_name%> optimize the use of system resources and reduce thread contention. This sets an initial parameter on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries.
 <div class="note note">
@@ -1928,7 +1928,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>16 (threads)</td>
 </tr>
-<tr class="even">
+<tr>
 <td>data-policy</td>
 <td><p>Specifies how the local cache handles data for a region. This setting controls behavior such as local data storage and region initialization.</p>
 <div class="note note">
@@ -1939,31 +1939,31 @@
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>empty</td>
 <td>No data storage in the local cache. The region always appears empty. Use this for event delivery to and from the local cache without the memory overhead of data storage - zero-footprint producers that only distribute data to others and zero-footprint consumers that only see events. To receive events with this, set the region's <code class="ph codeph">subscription-attributes</code> <code class="ph codeph">interest-policy</code> to all.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>normal</td>
 <td>Data used locally (accessed with <code class="ph codeph">get</code>s, stored with <code class="ph codeph">put</code>s, etc.) is stored in the local cache. This policy allows the contents in the cache to differ from other caches.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>partition</td>
 <td>Data is partitioned across local and remote caches using the automatic data distribution behavior of partitioned regions. Additional configuration is done in the <code class="ph codeph">partition-attributes</code>.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>replicate</td>
 <td>The region is initialized with the data from other caches. After initialization, all events for the distributed region are automatically copied into the local region, maintaining a replica of the entire distributed region in the local cache. Operations that would cause the contents to differ with other caches are not allowed. This is compatible with local <code class="ph codeph">scope</code>, behaving the same as for normal.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>persistent-partition</td>
 <td>Behaves the same as <code class="ph codeph">partition</code> and also persists data to disk.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>persistent-replicate</td>
 <td>Behaves the same as <code class="ph codeph">replicate</code> and also persists data to disk.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>preloaded</td>
 <td>Initializes like a replicated region, then, once initialized, behaves like a normal region.</td>
 </tr>
@@ -1982,7 +1982,7 @@
 <p>If you use <code class="ph codeph">data-policy</code>, you must set the scope explicitly.</p></td>
 <td>normal</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-async-conflation</td>
 <td><p>For TCP/IP distributions between peers, specifies whether to allow aggregation of asynchronous messages sent by the producer member for the region. This is a special-purpose voolean attribute that applies only when asynchronous queues are used for slow consumers. A false value disables conflation so that all asynchronous messages are sent individually. This special-purpose attribute gives you extra control over peer-to-peer communication between distributed regions using TCP/IP. This attribute does not apply to client/server communication or to communication using the UDP unicast or IP multicast protocols.</p>
 <div class="note note">
@@ -1996,13 +1996,13 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>enable-gateway</td>
 <td><p>Determines whether the gateway is enabled for the region. When set to true, events in the region are sent to the defined gateway hubs.</p>
 Used only with GemFire version 6.x gateway configurations. For GemFire 7.0 configuration, see the <code class="ph codeph">gateway-sender-id</code> attribute of the <code class="ph codeph">&lt;region-attributes&gt;</code> element.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-subscription-conflation</td>
 <td><p>Boolean for server regions that specifies whether the server can conflate its messages to the client. A true value enables conflation.</p>
 <div class="note note">
@@ -2016,7 +2016,7 @@
  &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>gateway-sender-ids</td>
 <td><p>Specifies one or more gateway sender IDs to use for distributing region events to remote <%=vars.product_name%> sites. Specify multiple IDs as a comma-separated list.</p>
 <p><strong>API:</strong> <code class="ph codeph">addGatewaySenderId</code></p>
@@ -2026,7 +2026,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>async-event-queue-ids</td>
 <td>Specifies one or more asynchronous event queues to use for distributing region events an <code class="ph codeph">AsyncEventListener</code> implementation (for example, for write-behind cache event handling). Specify multiple IDs as a comma-separated list.
 <p><strong>API</strong>: <code class="ph codeph">addAsyncEventQueueId</code></p>
@@ -2036,13 +2036,13 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>hub-id</td>
 <td><p>If the <code class="ph codeph">enable-gateway</code> attribute is set to true, a comma-separated list of gateway hub IDs that receive events from the region.</p>
 <p>Used only with GemFire version 6.x gateway configurations. For GemFire 7.0 configuration, see the <code class="ph codeph">gateway-sender-id</code> attribute of the <code class="ph codeph">&lt;region-attributes&gt;</code> element.</p></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>id</td>
 <td><p>Stores the region attribute settings in the cache with this identifier. Once stored, the attributes can be retrieved using the region attribute <code class="ph codeph">refid</code>.</p>
 <p><strong>API:</strong> <code class="ph codeph">setId</code></p>
@@ -2052,7 +2052,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ignore-jta</td>
 <td><p>Boolean that determines whether operations on this region participate in active JTA transactions or ignore them and operate outside of the transactions. This is primarily used in cache loaders, writers, and listeners that need to perform non-transactional operations on a region, such as caching a result set.</p>
 <p><strong>API:</strong> <code class="ph codeph">setIgnoreJTA</code></p>
@@ -2062,7 +2062,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>index-update-type</td>
 <td><p>Specifies whether region indexes are maintained synchronously with region modifications, or asynchronously in a background thread. In the <code class="ph codeph">cache.xml</code> file, this is set as a value, asynchronous or synchronous, assigned to the <code class="ph codeph">index-update-type</code> region attribute. Set this through the API by passing a boolean to the <code class="ph codeph">setIndexMaintenanceSynchronous</code> method.</p>
 <p><strong>API:</strong> <code class="ph codeph">setIndexMaintenanceSynchronous</code></p>
@@ -2072,7 +2072,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>synchronous updates</td>
 </tr>
-<tr class="even">
+<tr>
 <td>initial-capacity</td>
 <td><p>Together with the <code class="ph codeph">load-factor</code> region attribute, sets the initial parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries.</p>
 <p><strong>API:</strong> <code class="ph codeph">setInitialCapacity</code></p>
@@ -2082,7 +2082,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>16</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>is-lock-grantor</td>
 <td><p>Determines whether this member defines itself as the lock grantor for the region at region creation time. This only specifies whether the member becomes lock grantor at creation and does not reflect the current state of the member’s lock grantor status. The member’s lock grantor status may change if another member subsequently defines the region with <code class="ph codeph">is-lock-grantor</code> set to true. This attribute is only relevant for regions with <code class="ph codeph">global</code> <code class="ph codeph">scope</code>, as only they allow locking. It affects implicit and explicit locking.</p>
 <p><strong>API:</strong> <code class="ph codeph">setLockGrantor</code></p>
@@ -2092,7 +2092,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>load-factor</td>
 <td><p>Together with the initial-capacity region attribute, sets the initial parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries. This must be a floating point number between 0 and 1, inclusive.</p>
 <div class="note note">
@@ -2106,12 +2106,12 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>.75</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>mirror-type</td>
 <td>Deprecated</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td>multicast-enabled</td>
 <td><p>Boolean that specifies whether distributed operations on a region should use multicasting. To enable this, multicast must be enabled for the cluster with the <code class="ph codeph">mcast-port</code> <code class="ph codeph">gemfire.properties</code> setting.</p>
 <p><strong>API:</strong> <code class="ph codeph">setMulticastEnabled</code></p>
@@ -2121,7 +2121,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>pool-name</td>
 <td><p>Identifies the region as a client region and specifies the server pool the region is to use. The named pool must be defined in the client cache before the region is created. If this is not set, the region does not connect to the servers as a client region.</p>
 <p><strong>API:</strong> <code class="ph codeph">setPoolName</code></p>
@@ -2156,7 +2156,7 @@
 &lt;/client-cache&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="even">
+<tr>
 <td>disk-store-name</td>
 <td><p>Assigns the region to the disk store with this name from the disk stores defined for the cache. Persist region data to disk by defining the region as persistent using the Shortcut Attribute Options or data-policy settings. Overflow data to disk by implementing LRU eviction-attributes with an action of overflow to disk. Each disk store defines the file system directories to use, how data is written to disk, and other disk storage maintenance properties. In addition, the <code class="ph codeph">disk-synchronous</code> region attribute specifies whether writes are done synchronously or asynchronously.</p>
 <p><strong>API:</strong> <code class="ph codeph">setDiskStoreName</code></p>
@@ -2166,7 +2166,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disk-synchronous</td>
 <td><p>For regions that write to disk, boolean that specifies whether disk writes are done synchronously for the region.</p>
 <p><strong>API:</strong> <code class="ph codeph">setDiskSynchronous</code></p>
@@ -2177,7 +2177,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>refid</td>
 <td><p>Retrieves region shortcuts and user-defined named region attributes for attributes initialization</p>
 <p><strong>API:</strong> <code class="ph codeph">setRefId</code></p>
@@ -2190,7 +2190,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>not set</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>scope</td>
 <td><p>Definition: Determines how updates to region entries are distributed to the other caches in the cluster where the region and entry are defined. Scope also determines whether to allow remote invocation of some of the region’s event handlers, and whether to use region entry versions to provide consistent updates across replicated regions.</p>
 <div class="note note">
@@ -2205,19 +2205,19 @@
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local</td>
 <td>No distribution. The region is visible only to threads running inside the member.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>distributed-no-ack</td>
 <td>Events are distributed to remote caches with no acknowledgement required.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>distributed-ack</td>
 <td>Events are distributed to remote caches with receipt acknowledgement required. Region entry versions are used to provide consistent updates across members of the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>global</td>
 <td>Events are distributed to remote caches with global locking to ensure distributed cache consistency.</td>
 </tr>
@@ -2231,7 +2231,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>distributed-no-ack</td>
 </tr>
-<tr class="even">
+<tr>
 <td>statistics-enabled</td>
 <td>Boolean specifying whether to gather statistics on the region. Must be true to use expiration on the region. <%=vars.product_name%> provides a standard set of statistics for cached regions and region entries, which give you information for fine-tuning your cluster. Unlike other <%=vars.product_name%> statistics, statistics for local and distributed regions are not archived and cannot be charted. They are kept in instances of <code class="ph codeph">org.apache.geode.cache.CacheStatistics</code> and made available through the region and its entries through the <code class="ph codeph">Region.getStatistics</code> and <code class="ph codeph">Region.Entry.getStatistics</code> methods.
 <p><strong>API:</strong> <code class="ph codeph">setStatisticsEnabled</code></p>
@@ -2241,7 +2241,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>cloning-enabled</td>
 <td><p>Determines how <code class="ph codeph">fromDelta</code> applies deltas to the local cache for delta propagation. When true, the updates are applied to a clone of the value and then the clone is saved to the cache. When false, the value is modified in place in the cache.</p>
 <p><strong>API:</strong> <code class="ph codeph">setCloningEnabled</code></p>
@@ -2251,7 +2251,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>concurrency-checks-enabled</td>
 <td><p>Determines whether members perform checks to provide consistent handling for concurrent or out-of-order updates to distributed regions. See [Consistency for Region Updates](../../developing/distributed_regions/region_entry_versions.html#topic_CF2798D3E12647F182C2CEC4A46E2045).</p>
 <div class="note note">
@@ -2265,7 +2265,7 @@
 &lt;/region-attributes&gt;</code></pre></td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>off-heap</td>
 <td><p>Specifies that the region uses off-heap memory to store entry values, including values for region entries and queue entries. The region will still use heap memory for everything else, such as entry keys and the ConcurrentHashMap.</p>
 <p><strong>API:</strong> <code class="ph codeph">setOffHeap</code></p>
@@ -2527,13 +2527,13 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>critical-heap-percentage</td>
 <td>Percentage of heap at or above which the cache is considered in danger of becoming inoperable due to garbage collection pauses or out of memory exceptions.
 <p>Only one change to this attribute or critical heap percentage will be allowed at any given time and its effect will be fully realized before the next change is allowed. This feature requires additional VM flags to perform properly. See <code class="ph codeph">setCriticalHeapPercentage()</code> for details.</p></td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-heap-percentage</td>
 <td><p>Set the percentage of heap at or above which the eviction should begin on Regions configured for HeapLRU eviction.</p>
 <p>Changing this value may cause eviction to begin immediately.</p></td>
@@ -2543,12 +2543,12 @@
 <li>80%, if <code class="ph codeph">critical-heap-percentage</code> is not configured.</li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>critical-off-heap-percentage</td>
 <td>Percentage of off-heap memory at or above which the cache is considered in danger of becoming inoperable due to garbage collection pauses or out of memory exceptions.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-off-heap-percentage</td>
 <td>Set the percentage of off-heap memory at or above which the eviction should begin on Regions configured for HeapLRU eviction.</td>
 <td><ul>
diff --git a/geode-docs/reference/topics/gemfire_properties.html.md.erb b/geode-docs/reference/topics/gemfire_properties.html.md.erb
index 120acfb..e294c58 100644
--- a/geode-docs/reference/topics/gemfire_properties.html.md.erb
+++ b/geode-docs/reference/topics/gemfire_properties.html.md.erb
@@ -44,13 +44,13 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>ack-severe-alert-threshold</td>
 <td>Number of seconds the cluster will wait after the <code class="ph codeph">ack-wait-threshold</code> for a message to be acknowledged before it issues an alert at severe level. A value of zero disables this feature.</td>
 <td>S, L</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>ack-wait-threshold</td>
 <td>Number of seconds a distributed message can wait for acknowledgment before it sends an alert to signal that something might be wrong with the system member that is unresponsive.
 <p>The waiter continues to wait. The alerts are logged in the system member’s log as warnings.</p>
@@ -58,19 +58,19 @@
 <td>S, L</td>
 <td>15</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>archive-disk-space-limit</td>
 <td>Maximum size (in megabytes) of all inactive statistic archive files combined. If this limit is exceeded, inactive archive files are deleted, oldest first, until the total size is within the limit. If set to zero, disk space use is unlimited.</td>
 <td>S, L</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>archive-file-size-limit</td>
 <td>The maximum size (in megabytes) of a single statistic archive file. Once this limit is exceeded, a new statistic archive file is created, and the current archive file becomes inactive. If set to zero, file size is unlimited.</td>
 <td>S, L</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>async-distribution-timeout</td>
 <td>The number of milliseconds a process that is publishing to this process should attempt to distribute a cache operation before switching over to asynchronous messaging for this process. The switch to asynchronous messaging lasts until this process catches up, departs, or some specified limit is reached, such as async-queue-timeout or async-max-queue-size.
 <p>To enable asynchronous messaging, the value must be set above zero. Valid values are in the range 0...60000.</p>
@@ -81,7 +81,7 @@
 <td>S</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>async-max-queue-size</td>
 <td>Affects non-conflated asynchronous queues for members that publish to this member. This is the maximum size the queue can reach (in megabytes) before the publisher asks this member to leave the cluster.
 <p>Valid values are in the range 0..1024.</p>
@@ -92,7 +92,7 @@
 <td>S</td>
 <td>8</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>async-queue-timeout</td>
 <td>Affects asynchronous queues for members that publish to this member. This is the maximum milliseconds the publisher should wait with no distribution to this member before it asks this member to leave the cluster. Used for handling slow receivers.
 <div class="note note">
@@ -102,70 +102,70 @@
 <td>S, L</td>
 <td>60000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>bind-address</td>
 <td>Relevant only for multi-homed hosts - machines with multiple network interface cards. Specifies the adapter card the cache binds to for peer-to-peer communication. Also specifies the default location for <%=vars.product_name%> servers to listen on, which is used unless overridden by the <code class="ph codeph">server-bind-address</code>. An empty string causes the member to listen on the default card for the machine. This is a machine-wide attribute used for system member and client/server communication. It has no effect on locator location, unless the locator is embedded in a member process.
 <p>Specify the IP address, not the hostname, because each network card may not have a unique hostname. An empty string (the default) causes the member to listen on the default card for the machine.</p></td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>cache-xml-file</td>
 <td>Declarative initialization file for the member's cache.</td>
 <td>S</td>
 <td>cache.xml</td>
 </tr>
-<tr class="even">
+<tr>
 <td>cluster-configuration-dir</td>
 <td>This property specifies the directory in which the cluster configuration related disk-store and artifacts are stored. This property is only applicable to dedicated locators that have &quot;enable-cluster-configuration&quot; set to true.</td>
 <td>L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>conflate-events</td>
 <td>Used only by clients in a client/server installation. This is a client-side property that is passed to the server. Affects subscription queue conflation in this client's servers. Specifies whether to conflate (true setting), not conflate (false), or to use the server's conflation setting (server).</td>
 <td>S</td>
 <td>server</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>conserve-sockets</td>
 <td>Specifies whether sockets are shared by the system member’s threads. If true, threads share, and a minimum number of sockets are used to connect to the cluster. If false, every application thread has its own sockets for distribution purposes. You can override this setting for individual threads inside your application. Where possible, it is better to set conserve-sockets to true and enable the use of specific extra sockets in the application code if needed. WAN deployments increase the messaging demands on a <%=vars.product_name%> system. To avoid hangs related to WAN messaging, always set <code class="ph codeph">conserve-sockets=false</code> for <%=vars.product_name%> members that participate in a WAN deployment.</td>
 <td>S, L</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>delta-propagation</td>
 <td>Specifies whether to distribute the deltas for entry updates, instead of the full values, between clients and servers and between peers.</td>
 <td>S</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>deploy-working-dir</td>
 <td>Working directory used when deploying JAR application files to cluster members. This directory can be local and unique to the member or a shared resource. 
 See <a href="../../configuring/cluster_config/deploying_application_jars.html">Deploying Application JARs to <%=vars.product_name_long%> Members</a> for more information.</td>
 <td>S</td>
 <td>. (current directory)</td>
 </tr>
-<tr class="even">
+<tr>
 <td>disable-auto-reconnect</td>
 <td>By default, a <%=vars.product_name%> member (both locators and servers) will attempt to reconnect and reinitialize the cache after it has been forced out of the cluster by a network partition event or has otherwise been shunned by other members. Use this property to turn off the autoreconnect behavior. 
 See <a href="../../managing/member-reconnect.html">Handling Forced Cache Disconnection Using Autoreconnect</a> for more details.</td>
 <td>S, L</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disable-jmx</td>
 <td>By default, <%=vars.product_name%> automatically creates JMX MBeans. This boolean, when true, prevents the creation of JMX MBeans. Both gfsh and Pulse require JMX MBeans.</td>
 <td>S, L</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>disable-tcp</td>
 <td>Boolean indicating whether to disable the use of TCP/IP sockets for inter-cache point-to-point messaging. If disabled, the cache uses datagram (UDP) sockets.</td>
 <td>S, L</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>distributed-system-id</td>
 <td>Identifier used to distinguish messages from different clusters. 
 This is required for Portable Data eXchange (PDX) data serialization. 
@@ -177,122 +177,122 @@
 <td>S, L</td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>durable-client-id</td>
 <td>Used only for clients in a client/server installation. If set, this indicates that the client is durable and identifies the client. The ID is used by servers to reestablish any messaging that was interrupted by client downtime.</td>
 <td>C</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>durable-client-timeout</td>
 <td>Used only for clients in a client/server installation. Number of seconds this client can remain disconnected from its server and have the server continue to accumulate durable events for it.</td>
 <td>C</td>
 <td>300</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-network-partition-detection</td>
 <td>Boolean instructing the system to detect and handle splits in the cluster, typically caused by a partitioning of the network (split brain) where the cluster is running. You must set this property to the same value across all your cluster members. In addition, this property must be set to <code class="ph codeph">true</code> if you are using persistent regions and configure your regions to use DISTRIBUTED_ACK or GLOBAL scope to avoid potential data conflicts.</td>
 <td>S, L</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td>enable-cluster-configuration</td>
 <td>A value of &quot;true&quot; causes the creation of cluster configuration on dedicated locators. The cluster configuration service on dedicated locator(s) with this property set to &quot;true&quot; would serve the configuration to new members joining the cluster and also save the configuration changes caused by the <code class="ph codeph">gfsh</code> commands. This property is only applicable to dedicated locators..</td>
 <td>L</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>enable-time-statistics</td>
 <td>Boolean instructing the system to track time-based statistics for the cluster and caching. Disabled by default for performance reasons and not recommended for production environments. You must also configure <code class="ph codeph">statistics-sampling-enabled</code> to true and specify a <code class="ph codeph">statistics-archive-file</code>.</td>
 <td>S, L</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>enforce-unique-host</td>
 <td>Whether partitioned regions will put redundant copies of the same data in different members running on the same physical machine. By default, <%=vars.product_name%> tries to put redundant copies on different machines, but it will put them on the same machine if no other machines are available. Setting this property to true prevents this and requires different machines for redundant copies.</td>
 <td>S</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>geode.disallow-internal-messages-without-credentials</td>
 <td>A boolean that enables internal message validation when true. Set this system property to true on the <code>gfsh start server</code> command line when restarting servers to work with upgraded clients.
 </td>
 <td>S</td>
 <td>false</td>
-<tr class="odd">
+<tr>
 <td>groups</td>
 <td>Defines the list of groups that this member belongs to. Use commas to separate group names. Note that anything defined by the roles gemfire property will also be considered a group. 
 See <a href="../../configuring/cluster_config/using_member_groups.html">Using Member Groups</a> for more information.</td>
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>http-service-bind-address</td>
 <td>If set, then the <%=vars.product_name%> member binds the embedded HTTP service to the specified address. If this property is not set but the HTTP service is enabled using <code class="ph codeph">http-service-port</code>, then <%=vars.product_name%> binds the HTTP service to the member's local address. Used by the <%=vars.product_name%> Pulse Web application and the developer REST API service.</td>
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>http-service-port</td>
 <td>If non-zero, then <%=vars.product_name%> starts an embedded HTTP service that listens on this port. The HTTP service is used to host the <%=vars.product_name%> Pulse Web application and the development REST API service. If you are hosting the Pulse web app on your own Web server and are not using the development REST API service, then disable this embedded HTTP service by setting this property to zero. Ignored if <code class="ph codeph">jmx-manager</code> and <code class="ph codeph">start-dev-rest-api</code> are both set to false.</td>
 <td>S</td>
 <td>7070</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager</td>
 <td>If true then this member is willing to be a JMX Manager. All the other JMX Manager properties will be used when it does become a manager. If this property is false then all other <code class="ph codeph">jmx-manager-*</code> properties are ignored.</td>
 <td>S, L</td>
 <td>false (except on locators)</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-bind-address</td>
 <td>By default the jmx-manager (when configured with a port) will listen on all the local host's addresses. You can use this property to configure what IP address or host name the JMX Manager will listen on for non-HTTP connections. Ignored if JMX Manager is false or <code class="ph codeph">jmx-manager-port</code> is zero.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jmx-manager-hostname-for-clients</td>
 <td>Lets you control what hostname will be given to clients that ask the locator for the location of a JMX Manager. By default the IP address that the jmx-manager reports is used. But for clients on a different network this property allows you to configure a different hostname that will be given to clients. Ignored if <code class="ph codeph">jmx-manager</code> is false or <code class="ph codeph">jmx-manager-port</code> is zero.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-http-port</td>
 <td><em>Deprecated.</em> Use <code class="ph codeph">http-service-port</code> instead.</td>
 <td>S, L</td>
 <td>7070</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-port</td>
 <td>The port this JMX Manager will listen to for client connections. If this property is set to zero then <%=vars.product_name%> will not allow remote client connections but you can alternatively use the standard system properties supported by the JVM for configuring access from remote JMX clients. Ignored if <code class="ph codeph">jmx-manager</code> is false.</td>
 <td>S, L</td>
 <td>1099</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>jmx-manager-start</td>
 <td>If true then this member will start a jmx manager when it creates a cache. Management tools like gfsh can be configured to connect to the jmx-manager. In most cases you should not set this because a jmx manager will automatically be started when needed on a member that sets &quot;jmx-manager&quot; to true. Ignored if jmx-manager is false.</td>
 <td>S, L</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>jmx-manager-update-rate</td>
 <td>The rate, in milliseconds, at which this member will push updates to any JMX Managers. Currently this value should be greater than or equal to the statistic-sample-rate. Setting this value too high will cause stale values to be seen by gfsh and <%=vars.product_name%> Pulse.</td>
 <td>S, L</td>
 <td>2000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>load-cluster-configuration-from-dir</td>
 <td>Setting this property to &quot;true&quot; causes loading of cluster configuration from &quot;cluster_config&quot; directory in the locator. This property is only applicable to dedicated locators that have &quot;enable-cluster-configuration&quot; set to true.</td>
 <td>L</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td>locator-wait-time</td>
 <td>The number of seconds that a member should wait for a locator to start if a locator is not available when attempting to join the cluster. Use this setting when you are starting locators and peers all at once. This timeout allows peers to wait for the locators to finish starting up before attempting to join the cluster.</td>
 <td>S</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>locators</td>
 <td><p>The list of locators used by system members. The list must be configured consistently for every member of the cluster. If the list is empty, locators are not used.</p>
 <p>For each locator, provide a host name and/or address (separated by ‘@’, if you use both), followed by a port number in brackets. Examples:</p>
@@ -311,19 +311,19 @@
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>lock-memory</td>
 <td>When <code class="ph codeph">true</code>, locks heap and off-heap memory into RAM to prevent the operating system from paging the memory out to disk.</td>
 <td>S, L</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>log-disk-space-limit</td>
 <td>Maximum size in megabytes of all inactive log files combined. If this limit is exceeded, inactive log files are deleted, oldest first, until the total size is within the limit. If set to zero, disk space use is unlimited.</td>
 <td>S, L</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>log-file</td>
 <td>File to which a running system member writes log messages. If set to null, the default is used.
 <p>Each member type has its own default output:</p>
@@ -335,26 +335,26 @@
 <td>S, L</td>
 <td>null</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>log-file-size-limit</td>
 <td>Maximum size in megabytes of a log file before it is closed and logging rolls on to a new (child) log file. If set to 0, log rolling is disabled.</td>
 <td>S, L</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td>log-level</td>
 <td>Level of detail of the messages written to the system member’s log. Setting log-level to one of the ordered levels causes all messages of that level and greater severity to be printed.
 <p>Valid values from lowest to highest are fine, config, info, warning, error, severe, and none.</p></td>
 <td>S, L</td>
 <td>config</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>max-wait-time-reconnect</td>
 <td>Maximum number of milliseconds to wait for the cluster to reconnect on each reconnect attempt.</td>
 <td>S, L</td>
 <td>60000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>mcast-address</td>
 <td>Address used to discover other members of the cluster. Only used if mcast-port is non-zero. This attribute must be consistent across the cluster. Select different multicast addresses and different ports for different clusters. Do not just use different addresses. Some operating systems may not keep communication separate between systems that use unique addresses but the same port number.
 <p>This default multicast address was assigned by IANA
@@ -367,7 +367,7 @@
 <td><p>239.192.81.1 for IPv4 (the default IP version)</p>
 <p>FF38::1234 for IPv6</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>mcast-flow-control</td>
 <td>Tuning property for flow-of-control protocol for unicast and multicast no-ack UDP messaging. Compound property made up of three settings separated by commas: byteAllowance, rechargeThreshold, and rechargeBlockMs.
 <p>Valid values range from these minimums: 10000,0.1,500 to these maximums: no_maximum ,0.5,60000.</p>
@@ -378,7 +378,7 @@
 <td>S, L</td>
 <td>1048576,0.25, 5000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>mcast-port</td>
 <td>Port used, along with the mcast-address, for multicast communication with other members of the cluster. If zero, multicast is disabled.
 <div class="note note">
@@ -394,7 +394,7 @@
 <td>S, L</td>
 <td>10334</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>mcast-recv-buffer-size</td>
 <td>Size of the socket buffer used for incoming multicast transmissions. You should set this high if there will be high volumes of messages.
 <p>Valid values are in the range 2048.. OS_maximum.</p>
@@ -409,7 +409,7 @@
 <td>S, L</td>
 <td>1048576</td>
 </tr>
-<tr class="even">
+<tr>
 <td>mcast-send-buffer-size</td>
 <td>The size of the socket buffer used for outgoing multicast transmissions.
 <p>Valid values are in the range 2048.. OS_maximum.</p>
@@ -420,7 +420,7 @@
 <td>S, L</td>
 <td>65535</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>mcast-ttl</td>
 <td>How far multicast messaging goes in your network. Lower settings may improve system performance. A setting of 0 constrains multicast messaging to the machine.
 <div class="note note">
@@ -430,14 +430,14 @@
 <td>S, L</td>
 <td>32</td>
 </tr>
-<tr class="even">
+<tr>
 <td>member-timeout</td>
 <td><%=vars.product_name%> uses the <code class="ph codeph">member-timeout</code> server configuration, specified in milliseconds, to detect the abnormal termination of members. The configuration setting is used in two ways: 1) First it is used during the UDP heartbeat detection process. When a member detects that a heartbeat datagram is missing from the member that it is monitoring after the time interval of 2 * the value of <code class="ph codeph">member-timeout</code>, the detecting member attempts to form a TCP/IP stream-socket connection with the monitored member as described in the next case. 2) The property is then used again during the TCP/IP stream-socket connection. If the suspected process does not respond to the <em>are you alive</em> datagram within the time period specified in <code class="ph codeph">member-timeout</code>, the membership coordinator sends out a new membership view that notes the member's failure.
 <p>Valid values are in the range 1000..600000.</p></td>
 <td>S, L</td>
 <td>5000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>membership-port-range</td>
 <td>The range of ports available for unicast UDP messaging and for TCP failure detection. This is specified as two integers separated by a hyphen. Different members can use different ranges.
 <p><%=vars.product_name%> randomly chooses at least two unique integers from this range for the member, one for UDP unicast messaging and the other for TCP failure detection messaging. If tcp-port is configured to 0, it will also randomly select a port from this range for TCP sockets used for peer-to-peer communication only.</p>
@@ -447,25 +447,25 @@
 <td>S, L</td>
 <td>41000-61000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>memcached-port</td>
 <td>If specified and is non-zero, sets the port number for an embedded Gemcached server and starts the Gemcached server.</td>
 <td>S</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>memcached-protocol</td>
 <td>Sets the protocol used by an embedded Gemcached server. Valid values are <code class="ph codeph">BINARY</code> and <code class="ph codeph">ASCII.</code> If you omit this property, the ASCII protocol is used.</td>
 <td>S</td>
 <td>ASCII</td>
 </tr>
-<tr class="even">
+<tr>
 <td>name</td>
 <td>Symbolic name used to identify this system member.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>off-heap-memory-size</td>
 <td>Specifies the size of off-heap memory in megabytes (m) or gigabytes (g). For example:
 <pre class="pre codeblock"><code>off-heap-memory-size=4096m
@@ -473,14 +473,14 @@
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>redundancy-zone</td>
 <td>Defines this member's redundancy zone. Used to separate member's into different groups for satisfying partitioned region redundancy. If this property is set, <%=vars.product_name%> will not put redundant copies of data in members with the same redundancy zone setting. 
 See <a href="../../developing/partitioned_regions/configuring_ha_for_pr.html">Configure High Availability for a Partitioned Region</a> for more details.</td>
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>remote-locators</td>
 <td>Used to configure the locators that a cluster will use in order to connect to a remote site in a multi-site (WAN) configuration. To use locators in a WAN configuration, you must specify a unique distributed system ID (<code class="ph codeph">distributed-system-id</code>) for the local cluster and remote locator(s) for the remote clusters to which you will connect.
 <p>For each remote locator, provide a host name and/or address (separated by ‘@’, if you use both), followed by a port number in brackets. Examples:</p>
@@ -490,13 +490,13 @@
 <td>L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>remove-unresponsive-client</td>
 <td>When this property is set to true, the primary server drops unresponsive clients from all secondaries and itself. Clients are deemed unresponsive when their messaging queues become full on the server. While a client's queue is full, puts that would add to the queue block on the server.</td>
 <td>S</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>security-*</td>
 <td>
 Any security-related (properties that begin with <code class="ph codeph">security-</code>) configuration properties that are normally configured in <code class="ph codeph">gemfire.properties</code> can be moved to a separate <code class="ph codeph">gfsecurity.properties</code> file. Placing these configuration settings in a separate file allows you to restrict access to security configuration data. This way, you can still allow read or write access for your <code class="ph codeph">gemfire.properties</code> file.
@@ -504,94 +504,94 @@
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-client-accessor</td>
 <td><b>Deprecated.</b> Used for authorization. Static creation method returning an <code class="ph codeph">AccessControl</code> object, which determines authorization of client-server cache operations. This specifies the callback that should be invoked in the pre-operation phase, which is when the request for the operation is received from the client.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>security-client-accessor-pp</td>
 <td><b>Deprecated.</b> Used for authorization. The callback that should be invoked in the post-operation phase, which is when the operation has completed on the server but before the result is sent to the client. The post-operation callback is also invoked for the updates that are sent from server to client through the notification channel.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-client-auth-init</td>
 <td>Used for authentication. Static creation method returning an <code class="ph codeph">AuthInitialize</code> object, which obtains credentials for peers in a cluster. The obtained credentials should be acceptable to the <code class="ph codeph">Authenticator</code> specified through the security-peer-authenticator property on the peers.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>security-client-authenticator</td>
 <td><b>Deprecated.</b> Used for authentication. Static creation method returning an <code class="ph codeph">Authenticator</code> object, which is used by a peer to verify the credentials of the connecting peer.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-client-dhalgo</td>
 <td><strong>Deprecated.</strong> Use <code class="ph codeph">ssl-enabled-components</code> instead.
 <br>Used for authentication. For secure transmission of sensitive credentials like passwords, you can encrypt the credentials using the Diffie-Hellman key-exchange algorithm. Do this by setting the security-client-dhalgo system property on the clients to the name of a valid, symmetric key cipher supported by the JDK.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>security-log-file</td>
 <td>Used with authentication. The log file for security log messages. If not specified, the member's regular log file is used.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-log-level</td>
 <td>Used with authentication. Logging level detail for security log messages.
 <p>Valid values from lowest to highest are fine, config, info, warning, error, severe, and none.</p></td>
 <td>S, L</td>
 <td>config</td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-manager</td>
 <td>Specifies the implementation of the <code>SecurityManager</code> interface that implements the callbacks that do authentication and authorization.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>security-peer-auth-init</td>
 <td><b>Deprecated.</b> Used with authentication. Static creation method returning an <code class="ph codeph">AuthInitialize</code> object, which obtains credentials for peers in a cluster. The obtained credentials should be acceptable to the <code class="ph codeph">Authenticator</code> specified through the security-peer-authenticator property on the peers.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-peer-authenticator</td>
 <td><b>Deprecated.</b> Used with authentication. Static creation method returning an <code class="ph codeph">Authenticator</code> object, which is used by a peer to verify the credentials of the connecting peer.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>security-peer-verifymember-timeout</td>
 <td>Used with authentication. Timeout in milliseconds used by a peer to verify membership of an unknown authenticated peer requesting a secure connection.</td>
 <td>S, L</td>
 <td>1000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-post-processor</td>
 <td>Specifies the implementation of the <code>PostProcessor</code> interface that implements user-defined callbacks that can change the returned results of region get operations.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>security-udp-dhalgo</td>
 <td>Specifies a string that defines the name of a valid, symmetric key cipher supported by the JDK. When defined, the named cipher will be used for server-to-server UDP communications.</td>
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>serializable-object-filter</td>
 <td>A semicolon-separated list of items that become full class names of objects that the system will serialize when the property validate-serializable-objects is set to true. The list is expanded using the patterns specified in the <code>createFilter</code> method at
 <a href="https://docs.oracle.com/javase/9/docs/api/java/io/ObjectInputFilter.Config.html">https://docs.oracle.com/javase/9/docs/api/java/io/ObjectInputFilter.Config.html</a>.</td>
 <td>S, C</td>
 <td>"!*"</td>
 </tr>
-<tr class="even">
+<tr>
 <td>server-bind-address</td>
 <td>Relevant only for multi-homed hosts - machines with multiple network interface cards. Network adapter card a <%=vars.product_name%> server binds to for client/server communication. You can use this to separate the server’s client/server communication from its peer-to-peer communication, spreading the traffic load.
 <p>This is a machine-wide attribute used for communication with clients in client/server and multi-site installations. This setting has no effect on locator configuration.</p>
@@ -600,13 +600,13 @@
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>socket-buffer-size</td>
 <td>Receive buffer sizes in bytes of the TCP/IP connections used for data transmission. To minimize the buffer size allocation needed for distributing large, serializable messages, the messages are sent in chunks. This setting determines the size of the chunks. Larger buffers can handle large messages more quickly, but take up more memory.</td>
 <td>S, L</td>
 <td>32768</td>
 </tr>
-<tr class="even">
+<tr>
 <td>socket-lease-time</td>
 <td>Time, in milliseconds, a thread can have exclusive access to a socket it is not actively using. A value of zero causes socket leases to never expire. This property is ignored if conserve-sockets is true.
 <p>Valid values are in the range 0..600000.</p></td>
@@ -699,13 +699,13 @@
 <td>JKS</td>
 </tr>
 
-<tr class="even">
+<tr>
 <td>start-dev-rest-api</td>
 <td>If set to true, then the developer REST API service will be started when cache is created. REST service can be configured using <code class="ph codeph">http-service-port</code> and <code class="ph codeph">http-service-bind-address</code> properties.</td>
 <td>S</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>start-locator</td>
 <td>If set, automatically starts a locator in the current process when the member connects to the cluster and stops the locator when the member disconnects.
 <p>To use, specify the locator with an optional address or host specification and a required port number, in one of these formats:</p>
@@ -716,20 +716,20 @@
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>statistic-archive-file</td>
 <td>The file to which the running system member writes statistic samples. For example: &quot;StatisticsArchiveFile.gfs&quot;. An empty string disables archiving. Adding .gz suffix to the file name causes it to be compressed.</td>
 <td>S, L</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>statistic-sample-rate</td>
 <td>How often to sample statistics, in milliseconds.
 <p>Valid values are in the range 100..60000.</p></td>
 <td>S, L</td>
 <td>1000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>statistic-sampling-enabled</td>
 <td>Whether to collect and archive statistics on the member.
 <p>Statistics sampling provides valuable information for ongoing system tuning and troubleshooting purposes. Sampling statistics at the default sample rate does not impact system performance. We recommend enabling statistics sampling in production environments.</p>
@@ -740,7 +740,7 @@
 <td>S, L</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>tcp-port</td>
 <td>The TCP port to listen on for cache communications. If set to zero, the operating system selects an available port. Each process on a machine must have its own TCP port. Note that some operating systems restrict the range of ports usable by non-privileged users, and using restricted port numbers can cause runtime errors in <%=vars.product_name%> startup.
 <p>Valid values are in the range 0..65535.</p></td>
@@ -771,21 +771,21 @@
 <td>S</td>
 <td>30000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>tombstone-gc-threshold</td>
 <td>The number of tombstones that can accumulate before the <%=vars.product_name%> member triggers garbage collection for tombstones. 
 See <a href="../../developing/distributed_regions/how_region_versioning_works.html#topic_321B05044B6641FCAEFABBF5066BD399">How Destroy and Clear Operations Are Resolved</a>.</td>
 <td>S</td>
 <td>100000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>udp-fragment-size</td>
 <td>Maximum fragment size, in bytes, for transmission over UDP unicast or multicast sockets. Smaller messages are combined, if possible, for transmission up to the fragment size setting.
 <p>Valid values are in the range 1000..60000.</p></td>
 <td>S, L</td>
 <td>60000</td>
 </tr>
-<tr class="even">
+<tr>
 <td>udp-recv-buffer-size</td>
 <td>The size of the socket buffer used for incoming UDP point-to-point transmissions. If disable-tcp is false, a reduced buffer size of 65535 is used by default.
 <p>The default setting of 1048576 is higher than the default OS maximum buffer size on Unix, which should be increased to at least 1 megabyte to provide high-volume messaging on Unix systems.</p>
@@ -793,26 +793,26 @@
 <td>S, L</td>
 <td>1048576</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>udp-send-buffer-size</td>
 <td>The size of the socket buffer used for outgoing UDP point-to-point transmissions.
 <p>Valid values are in the range 2048..OS_maximum.</p></td>
 <td>S, L</td>
 <td>65535</td>
 </tr>
-<tr class="even">
+<tr>
 <td>use-cluster-configuration</td>
 <td>This property is only applicable for data members (non-client and non-locator). A value of &quot;true&quot; causes a member to request and use the configuration from cluster configuration services running on dedicated locators. Setting this property to &quot;false&quot; causes a member to not request the configuration from the configuration services running on the locator(s).</td>
 <td>S</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>user-command-packages</td>
 <td>A comma separated list of Java packages that contain classes implementing the <code class="ph codeph">CommandMarker</code> interface. Matching classes will be loaded when the VM starts and will be available in the GFSH command-line utility.</td>
 <td>S</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="even">
+<tr>
 <td>validate-serializable-objects</td>
 <td>A boolean that defaults to false. When true, instances of classes that are not internal to <%=vars.product_name%> and whose class name is not allowed by the list defined in the serializable-object-filter property will not be permitted to be deserialized. An <code>IncompatibleClassException</code> is thrown for objects not listed. JDK 8 build 121 or a later build must be installed to use this property. Servers and clients that do not meet this requirement will throw an exception upon startup.</td>
 <td>S, C</td>
diff --git a/geode-docs/reference/topics/memory_requirements_for_cache_data.html.md.erb b/geode-docs/reference/topics/memory_requirements_for_cache_data.html.md.erb
index b694a26..ba44676 100644
--- a/geode-docs/reference/topics/memory_requirements_for_cache_data.html.md.erb
+++ b/geode-docs/reference/topics/memory_requirements_for_cache_data.html.md.erb
@@ -127,7 +127,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>For each region
 <div class="note note">
 <b>Note:</b>
@@ -135,36 +135,36 @@
 </div></td>
 <td>add 64 bytes per entry</td>
 </tr>
-<tr class="even">
+<tr>
 <td>And concurrency checking is disabled (it is enabled by default)</td>
 <td>subtract 16 bytes per entry
 <p>(See <a href="../../developing/distributed_regions/how_region_versioning_works.html#topic_0BDACA590B2C4974AC9C450397FE70B2">Overhead for Consistency Checks</a>.)</p></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>And statistics are enabled for the region</td>
 <td>add 16 bytes per entry</td>
 </tr>
-<tr class="even">
+<tr>
 <td>And the region is persisted</td>
 <td>add 52 bytes per entry</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>And the region is overflow only</td>
 <td>add 44 bytes per entry</td>
 </tr>
-<tr class="even">
+<tr>
 <td>And the region has an LRU eviction controller</td>
 <td>add 16 bytes per entry</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>And the region has global scope</td>
 <td>add 110 bytes per entry</td>
 </tr>
-<tr class="even">
+<tr>
 <td>And the region has entry expiration configured</td>
 <td>add 112 bytes per entry</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>For each optional user attribute</td>
 <td>add 40 bytes per entry plus the memory overhead of the user attribute object</td>
 </tr>
@@ -252,24 +252,24 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>Per socket</td>
 <td><p>32,768 /socket (configurable)</p>
 <p>Default value per socket should be set to a number &gt; 100 + sizeof (largest object in region) + sizeof (largest key)</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td>If server (for example if there are clients that connect to it)</td>
 <td>= (lesser of max-threads property on server or max-connections)* (socket buffer size +thread overhead for the JVM )</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Per member of the cluster if conserve sockets is set to true</td>
 <td>4* number of peers</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Per member, if conserve sockets is set to false</td>
 <td>4 * number of peers hosting that region* number of threads</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>If member hosts a Partitioned Region, If conserve sockets set to false and it is a Server (this is cumulative with the above)</td>
 <td><p>=&lt; max-threads * 2 * number of peers</p>
 <div class="note note">
@@ -277,23 +277,23 @@
 <p>it is = 2* current number of clients connected * number of peers. Each connection spawns a thread.</p>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>Subscription Queues</strong></td>
 <td></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>Per Server, depending on whether you limit the queue size. If you do, you can specify the number of megabytes or the number of entries until the queue overflows to disk. When possible, entries on the queue are references to minimize memory impact. The queue consumes memory not only for the key and the entry but also for the client ID/or thread ID as well as for the operation type. Since you can limit the queue to 1 MB, this number is completely configurable and thus there is no simple formula.</p></td>
 <td>1 MB +</td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong><%=vars.product_name%> classes and JVM overhead</strong></td>
 <td>Roughly 50MB</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>Thread overhead</strong></td>
 <td></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>Each concurrent client connection into the a server results in a thread being spawned up to max-threads setting. After that a thread services multiple clients up to max-clients setting.</p></td>
 <td>There is a thread stack overhead per connection (at a minimum 256KB to 512 KB, you can set it to smaller to 128KB on many JVMs.)</td>
 </tr>
diff --git a/geode-docs/reference/topics/region_shortcuts_reference.html.md.erb b/geode-docs/reference/topics/region_shortcuts_reference.html.md.erb
index 1535bfa..8719964 100644
--- a/geode-docs/reference/topics/region_shortcuts_reference.html.md.erb
+++ b/geode-docs/reference/topics/region_shortcuts_reference.html.md.erb
@@ -1074,11 +1074,11 @@
 <col width="50%" />
 </colgroup>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>local-destroy
 <div class="note note">
diff --git a/geode-docs/reference/topics/region_shortcuts_table.html.md.erb b/geode-docs/reference/topics/region_shortcuts_table.html.md.erb
index 2571846..6b99e74 100644
--- a/geode-docs/reference/topics/region_shortcuts_table.html.md.erb
+++ b/geode-docs/reference/topics/region_shortcuts_table.html.md.erb
@@ -41,7 +41,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><p><a href="region_shortcuts_reference.html#reference_w2h_3cd_lk">LOCAL</a></p></td>
 <td><div id="reference_ufj_5kz_4k__p_q44_t11_nk" class="p">
 scope:
@@ -51,7 +51,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><p><a href="region_shortcuts_reference.html#reference_wd5_lpy_lk">LOCAL_HEAP_LRU</a></p></td>
 <td><div id="reference_ufj_5kz_4k__p_axf_z11_nk" class="p">
 scope:
@@ -63,11 +63,11 @@
 <span class="keyword parmname">Eviction Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>local-destroy</td>
 </tr>
@@ -75,7 +75,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[LOCAL_OVERFLOW](region_shortcuts_reference.html#reference_adk_y4y_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_fsq_jc1_nk" class="p">
 scope:
@@ -87,11 +87,11 @@
 <div id="reference_ufj_5kz_4k__p_rsq_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -99,7 +99,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[LOCAL_PERSISTENT](region_shortcuts_reference.html#reference_l5r_y4y_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_ctq_jc1_nk" class="p">
 scope:
@@ -109,7 +109,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[LOCAL\_PERSISTENT\_OVERFLOW](region_shortcuts_reference.html#reference_a45_y4y_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_ttq_jc1_nk" class="p">
 scope:
@@ -121,11 +121,11 @@
 <div id="reference_ufj_5kz_4k__p_e5q_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -133,7 +133,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[PARTITION](region_shortcuts_reference.html#reference_ow5_4qy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_p5q_jc1_nk" class="p">
 data-policy:
@@ -141,7 +141,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[PARTITION\_HEAP\_LRU](region_shortcuts_reference.html#reference_twx_y4y_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_bvq_jc1_nk" class="p">
 data-policy:
@@ -151,11 +151,11 @@
 <div id="reference_ufj_5kz_4k__p_lvq_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>local-destroy</td>
 </tr>
@@ -163,7 +163,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[PARTITION_OVERFLOW](region_shortcuts_reference.html#reference_js1_z4y_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_wvq_jc1_nk" class="p">
 data-policy:
@@ -173,11 +173,11 @@
 <div id="reference_ufj_5kz_4k__p_gwq_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -185,7 +185,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[PARTITION_PERSISTENT](region_shortcuts_reference.html#reference_d4k_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_qwq_jc1_nk" class="p">
 data-policy:
@@ -193,7 +193,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[PARTITION\_PERSISTENT\_OVERFLOW](region_shortcuts_reference.html#reference_v5l_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_axq_jc1_nk" class="p">
 data-policy:
@@ -203,11 +203,11 @@
 <div id="reference_ufj_5kz_4k__p_lxq_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -215,7 +215,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[PARTITION_PROXY](region_shortcuts_reference.html#reference_v4m_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_wxq_jc1_nk" class="p">
 data-policy:
@@ -225,7 +225,7 @@
 <span class="keyword parmname">Partition Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-max-memory:</td>
 <td>0</td>
 </tr>
@@ -233,7 +233,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[PARTITION\_PROXY\_REDUNDANT](region_shortcuts_reference.html#reference_c1n_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_oyq_jc1_nk" class="p">
 data-policy:
@@ -243,11 +243,11 @@
 <span class="keyword parmname">Partition Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>redundant-copies:</td>
 <td>1</td>
 </tr>
-<tr class="even">
+<tr>
 <td>local-max-memory</td>
 <td>0</td>
 </tr>
@@ -255,7 +255,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[PARTITION_REDUNDANT](region_shortcuts_reference.html#reference_shn_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_gzq_jc1_nk" class="p">
 data-policy:
@@ -265,7 +265,7 @@
 <span class="keyword parmname">Partition Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>redundant-copies:</td>
 <td>1</td>
 </tr>
@@ -273,7 +273,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td>[PARTITION\_REDUNDANT\_HEAP_LRU](region_shortcuts_reference.html#reference_m4n_jpy_lk)</td>
 <td><div id="reference_ufj_5kz_4k__p_szq_jc1_nk" class="p">
 data-policy:
@@ -283,11 +283,11 @@
 <div id="reference_ufj_5kz_4k__p_a1r_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>local-destroy</td>
 </tr>
@@ -298,7 +298,7 @@
 <span class="keyword parmname">Partition Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>redundant-copies:</td>
 <td>1</td>
 </tr>
@@ -306,7 +306,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[PARTITION\_REDUNDANT\_OVERFLOW](region_shortcuts_reference.html#reference_own_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_n1r_jc1_nk" class="p">
 data-policy:
@@ -316,11 +316,11 @@
 <div id="reference_ufj_5kz_4k__p_w1r_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -331,7 +331,7 @@
 <span class="keyword parmname">Partition Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>redundant-copies:</td>
 <td>1</td>
 </tr>
@@ -339,7 +339,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[PARTITION\_REDUNDANT\_PERSISTENT](region_shortcuts_reference.html#reference_bd4_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_jbr_jc1_nk" class="p">
 data-policy:
@@ -349,7 +349,7 @@
 <span class="keyword parmname">Partition Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>redundant-copies:</td>
 <td>1</td>
 </tr>
@@ -357,7 +357,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[PARTITION\_REDUNDANT\_PERSISTENT_OVERFLOW](region_shortcuts_reference.html#reference_xqq_tvc_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_xbr_jc1_nk" class="p">
 data-policy:
@@ -367,11 +367,11 @@
 <div id="reference_ufj_5kz_4k__p_fcr_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -382,7 +382,7 @@
 <span class="keyword parmname">Partition Attributes</span>
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>redundant-copies:</td>
 <td>1</td>
 </tr>
@@ -390,7 +390,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[REPLICATE](region_shortcuts_reference.html#reference_wq4_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_tcr_jc1_nk" class="p">
 data-policy:
@@ -400,7 +400,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[REPLICATE\_HEAP\_LRU](region_shortcuts_reference.html#reference_xx4_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_cdr_jc1_nk" class="p">
 data-policy:
@@ -416,11 +416,11 @@
 <col width="50%" />
 </colgroup>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>local-destroy
 <div class="note note">
@@ -435,7 +435,7 @@
 <div id="reference_ufj_5kz_4k__p_pdr_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>interest-policy:</td>
 <td>all</td>
 </tr>
@@ -443,7 +443,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[REPLICATE_OVERFLOW](region_shortcuts_reference.html#reference_t2p_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_wdr_jc1_nk" class="p">
 data-policy:
@@ -455,11 +455,11 @@
 <div id="reference_ufj_5kz_4k__p_f2r_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -467,7 +467,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[REPLICATE_PERSISTENT](region_shortcuts_reference.html#reference_emp_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_n2r_jc1_nk" class="p">
 data-policy:
@@ -477,7 +477,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><p>[REPLICATE\_PERSISTENT\_OVERFLOW](region_shortcuts_reference.html#reference_tsp_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_w2r_jc1_nk" class="p">
 data-policy:
@@ -489,11 +489,11 @@
 <div id="reference_ufj_5kz_4k__p_gfr_jc1_nk" class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>eviction-algorithm:</td>
 <td>lru-heap-percentage</td>
 </tr>
-<tr class="even">
+<tr>
 <td>eviction-action:</td>
 <td>overflow-to-disk</td>
 </tr>
@@ -501,7 +501,7 @@
 </table>
 </div></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><p>[REPLICATE_PROXY](region_shortcuts_reference.html#reference_n1q_jpy_lk)</p></td>
 <td><div id="reference_ufj_5kz_4k__p_pfr_jc1_nk" class="p">
 data-policy:
diff --git a/geode-docs/rest_apps/get_queries.html.md.erb b/geode-docs/rest_apps/get_queries.html.md.erb
index 5bf5555..e01cc5e 100644
--- a/geode-docs/rest_apps/get_queries.html.md.erb
+++ b/geode-docs/rest_apps/get_queries.html.md.erb
@@ -85,7 +85,7 @@
 <td>403 FORBIDDEN</td>
 <td>Insufficient privileges for operation</td>
 </tr>
-<tr class="even">
+<tr>
 <td>500 INTERNAL SERVER ERROR</td>
 <td>Error encountered at <%=vars.product_name%> server. Check the HTTP response body for a stack trace of the exception.</td>
 </tr>
diff --git a/geode-docs/rest_apps/post_create_query.html.md.erb b/geode-docs/rest_apps/post_create_query.html.md.erb
index 7401307..9f3976d 100644
--- a/geode-docs/rest_apps/post_create_query.html.md.erb
+++ b/geode-docs/rest_apps/post_create_query.html.md.erb
@@ -43,12 +43,12 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>id</td>
 <td><strong>Required.</strong> Unique identifier for the named parameterized query.</td>
 <td>selectCustomers</td>
 </tr>
-<tr class="even">
+<tr>
 <td>q</td>
 <td><strong>Required.</strong> OQL query statement. Use doublequotes to surround the OQL query statement.</td>
 <td><pre class="pre"><code>&quot;SELECT o FROM /orders o WHERE o.quantity &gt; $1 AND o.totalprice &gt; $2&quot;</code></pre></td>
@@ -105,7 +105,7 @@
 <td>409 CONFLICT</td>
 <td>QueryId already assigned to another query</td>
 </tr>
-<tr class="even">
+<tr>
 <td>500 INTERNAL SERVER ERROR</td>
 <td>Error encountered at <%=vars.product_name%> server. Check the HTTP response body for a stack trace of the exception.
 <ul>
diff --git a/geode-docs/rest_apps/post_execute_functions.html.md.erb b/geode-docs/rest_apps/post_execute_functions.html.md.erb
index 2548f9f..4cc8927 100644
--- a/geode-docs/rest_apps/post_execute_functions.html.md.erb
+++ b/geode-docs/rest_apps/post_execute_functions.html.md.erb
@@ -54,7 +54,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>
 <pre>myFunction1(int n)</pre>
 </td>
@@ -68,7 +68,7 @@
 ]
 </pre>
 </td></tr>
-<tr class="even">
+<tr>
 <td>
 <pre>myFunction2(double d, Item i)</pre>
 </td>
diff --git a/geode-docs/rest_apps/post_execute_query.html.md.erb b/geode-docs/rest_apps/post_execute_query.html.md.erb
index d3d7722..93c233e 100644
--- a/geode-docs/rest_apps/post_execute_query.html.md.erb
+++ b/geode-docs/rest_apps/post_execute_query.html.md.erb
@@ -43,12 +43,12 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>{queryId}</td>
 <td>QueryID for named query.</td>
 <td>selectOrders</td>
 </tr>
-<tr class="even">
+<tr>
 <td><em>query bind parameter values</em></td>
 <td>Bind parameters for the query are specified in the request body (JSON).</td>
 <td><p>Specify the parameter @type and @value for each bind parameter. For example, to provide values to the following query:</p>
@@ -162,7 +162,7 @@
 <td>404 NOT FOUND</td>
 <td>Query with specified ID could not be found</td>
 </tr>
-<tr class="even">
+<tr>
 <td>500 INTERNAL SERVER ERROR</td>
 <td>Encountered error at server:
 <ul>
diff --git a/geode-docs/rest_apps/put_update_cas_data.html.md.erb b/geode-docs/rest_apps/put_update_cas_data.html.md.erb
index 917d385..74f90d2 100644
--- a/geode-docs/rest_apps/put_update_cas_data.html.md.erb
+++ b/geode-docs/rest_apps/put_update_cas_data.html.md.erb
@@ -44,17 +44,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>op</td>
 <td>URL parameter. When you specify CAS for this parameter, data is only updated if the @old value specified in the request body matches the existing value in the region.</td>
 <td>CAS</td>
 </tr>
-<tr class="even">
+<tr>
 <td>@type</td>
 <td>Specified in the response body for both the old and new value. Use this to declare the domain object type of the entry's value.</td>
 <td>com.mycompany.ObjectName</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>@old</td>
 <td>Compare this value to the existing value in the region.</td>
 <td><pre class="pre codeblock"><code>{
@@ -79,7 +79,7 @@
          &quot;totalPrice&quot;: 225
     }</code></pre></td>
 </tr>
-<tr class="even">
+<tr>
 <td>@new</td>
 <td>If @old value matches existing value, use this value to replace the existing value.</td>
 <td><pre class="pre codeblock"><code>{
diff --git a/geode-docs/tools_modules/gemcached/deploying_gemcached.html.md.erb b/geode-docs/tools_modules/gemcached/deploying_gemcached.html.md.erb
index 68801eb..e25542a 100644
--- a/geode-docs/tools_modules/gemcached/deploying_gemcached.html.md.erb
+++ b/geode-docs/tools_modules/gemcached/deploying_gemcached.html.md.erb
@@ -74,12 +74,12 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><code class="ph codeph">memcached-port</code></td>
 <td><p>The port number where the Gemcached server listens for connections from memcached clients.</p>
 <p>If the port number is set to 0 or the <code class="ph codeph">memcached-port</code> parameter is omitted, the Gemcached server does not start.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td><code class="ph codeph">memcached-protocol</code></td>
 <td><p>Memcached supports both ASCII and binary communication protocols. 
 (See <a href="https://github.com/memcached/memcached/blob/master/doc/protocol.txt">Memcached protocol</a> By default, Gemcached uses the ASCII protocol.</p>
diff --git a/geode-docs/tools_modules/gfsh/cache_xml_2_gfsh.html.md.erb b/geode-docs/tools_modules/gfsh/cache_xml_2_gfsh.html.md.erb
index feccd65..5162cf5 100644
--- a/geode-docs/tools_modules/gfsh/cache_xml_2_gfsh.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/cache_xml_2_gfsh.html.md.erb
@@ -39,7 +39,7 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td>&lt;cache&gt;, &lt;cache-server&gt;</td>
 <td><ul>
 <li><a href="command-pages/start.html#topic_3764EE2DB18B4AE4A625E0354471738A">start server</a></li>
@@ -48,7 +48,7 @@
 <li><a href="command-pages/alter.html#topic_7E6B7E1B972D4F418CB45354D1089C2B">alter runtime</a></li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td>&lt;async-event-queue&gt;</td>
 <td><ul>
 <li><a href="command-pages/alter.html#topic_alter_async_event_queue">alter async-event-queue</a></li>
@@ -58,13 +58,13 @@
 <li><a href="command-pages/resume.html#topic_resume_async_event_queue_dispatcher">resume async-event-queue-dispatching</a></li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>&lt;pdx&gt;</td>
 <td><ul>
 <li><a href="command-pages/configure.html#topic_jdkdiqbgphqh">configure pdx</a></li>
 </td>
 </tr>
-<tr class="even">
+<tr>
 <td>&lt;region&gt;</td>
 <td><ul>
 <li><a href="command-pages/create.html#topic_54B0985FEC5241CA9D26B0CE0A5EA863">create region</a></li>
@@ -75,7 +75,7 @@
 <li><a href="command-pages/rebalance.html">rebalance</a></li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>&lt;index&gt;</td>
 <td><ul>
 <li><a href="command-pages/create.html#topic_960A5B6FD3D84E1881EE118E299DD12D">create index</a></li>
@@ -83,7 +83,7 @@
 <li><a href="command-pages/list.html#topic_B3B51B6DEA484EE086C4F657EC9831F2">list indexes</a></li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td>&lt;disk-store&gt;</td>
 <td><ul>
 <li><a href="command-pages/create.html#topic_bkn_zty_ck">create disk-store</a></li>
diff --git a/geode-docs/tools_modules/gfsh/command-pages/alter.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/alter.html.md.erb
index f7623c9..d009ac5 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/alter.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/alter.html.md.erb
@@ -106,39 +106,39 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-name</span></td>
 <td><em>Required</em>. Name of the disk-store whose contents will be altered.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-region</span></td>
 <td><em>Required</em>. Name (including path) of the region using the disk store.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-disk-dirs</span></td>
 <td><em>Required</em>. Directories where the data for the disk store was previously written.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-compressor</span></td>
 <td>The fully-qualified class name of the compressor to use when compressing region entry values. A value of <code class="ph codeph">none</code> removes the compressor.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-concurrency-level</span></td>
 <td>An estimate of the maximum number of application threads that will concurrently access a region entry. Together with <span class="keyword parmname">\-\-initial-capacity</span> and <span class="keyword parmname">\-\-load-factor</span>, sets the parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries. This attribute does not apply to partitioned regions.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-statistics</span></td>
 <td>Enables statistics for the region specified by the <code>--region</code> option. Valid values are true or false. If the parameter is specified without a value, the value of true is used.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-initial-capacity</span></td>
 <td>Together with <span class="keyword parmname">\-\-concurrency-level</span> and <span class="keyword parmname">\-\-load-factor</span>, sets the parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-load-factor</span></td>
 <td>Together with <span class="keyword parmname">\-\-concurrency-level</span> and <span class="keyword parmname">\-\-initial-capacity</span>, sets the parameters on the underlying <code class="ph codeph">java.util.ConcurrentHashMap</code> used for storing region entries. This must be a floating point number between 0 and 1, inclusive.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-lru-action</span></td>
 <td>Action to take when evicting entries from the region. Valid values are:
 <ul>
@@ -147,7 +147,7 @@
 <li><code class="ph codeph">local-destroy</code></li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-lru-algorithm</span></td>
 <td>Least recently used eviction algorithm. Valid types are:
 <ul>
@@ -157,15 +157,15 @@
 <li><code class="ph codeph">lru-memory-size</code></li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-lru-limit</span></td>
 <td>Number of entries allowed in the region before eviction occurs.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-off-heap</span></td>
 <td>Specifies whether the region values are in heap memory or off-heap memory. When true, region values are in off-heap memory. If the parameter is specified without a value, the value of true is used.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-remove</span></td>
 <td>Specifies whether to remove the region from the disk-store. If the parameter is specified without a value, the value of true is used. Note: <span class="keyword parmname">\-\-remove</span> deletes all persistent data for the region. Consider copying the disk store files to a backup before using this option if you might want to retrieve the data at a later date.</td>
 </tr>
@@ -223,56 +223,56 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-async-event-queue-id</span></td>
 <td>IDs of the Async Event Queues that will be used for write-behind operations.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-cache-listener</span></td>
 <td>Fully qualified class name of a plug-in to be instantiated for receiving after-event notification of changes to the region and its entries. Any number of cache listeners can be configured. A fully qualified class name may be appended with a JSON specification that will be parsed to become the fields of the parameter to the <code>init()</code> method for a class that implements the <code>Declarable</code> interface.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-cache-loader</span></td>
 <td>Fully qualified class name of a plug-in to be instantiated for receiving notification of cache misses in the region. At most, one cache loader can be defined in each member for the region. For distributed regions, a cache loader may be invoked remotely from other members that have the region defined. A fully qualified class name may be appended with a JSON specification that will be parsed to become the fields of the parameter to the <code>initialize()</code> method for a class that implements the <code>Declarable</code> interface.</td>
 <td></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-cache-writer</span></td>
 <td>Fully qualified class name of a plug-in to be instantiated for receiving before-event notification of changes to the region and its entries. The plug-in may cancel the event. At most, one cache writer can be defined in each member for the region. A fully qualified class name may be appended with a JSON specification that will be parsed to become the fields of the parameter to the <code>init()</code> method for a class that implements the <code>Declarable</code> interface.</td>
 <td></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-enable-cloning</span></td>
 <td><p>Determines how <code class="ph codeph">fromDelta</code> applies deltas to the local cache for delta propagation. When true, the updates are applied to a clone of the value and then the clone is saved to the cache. When false, the value is modified in place in the cache.</p></td>
 <td><code class="ph codeph">false</code></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-entry-idle-time-expiration</span></td>
 <td>Number of seconds before a region or an entry expires. Specify <code class="ph codeph">-1</code> to indicate that there is no expiration of this type</td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-idle-time-expiration-action</span></td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -281,31 +281,31 @@
 </div></td>
 <td><code class="ph codeph">invalidate</code></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-entry-time-to-live-expiration</span></td>
 <td>Number of seconds before a region or an entry expires. Specify <code class="ph codeph">-1</code> to indicate that there is no expiration of this type.</td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-time-to-live-expiration-action</span></td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -314,61 +314,61 @@
 </div></td>
 <td><code class="ph codeph">invalidate</code></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-idle-time-custom-expiry</span></td>
 <td>The name of a class implementing CustomExpiry for entry idle time. Append a JSON string for initialization properties.</td>
 <td></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-time-to-live-custom-expiry</span></td>
 <td>The name of a class implementing CustomExpiry for entry time to live. Append a JSON string for initialization properties.</td>
 <td></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-eviction-max</span></td>
 <td>Maximum value for the Eviction Attributes that the eviction algorithm uses to determine when to perform its eviction action. The unit of the maximum value is determined by the Eviction Algorithm.</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-gateway-sender-id</span></td>
 <td>IDs of the Gateway Senders where data is routed.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>Group(s) of members where the region will be altered.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-name</span></td>
 <td>Required. Name (including path) of the region.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-region-idle-time-expiration</span></td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-region-idle-time-expiration-action</span></td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -377,31 +377,31 @@
 </div></td>
 <td><code class="ph codeph">invalidate</code></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-region-time-to-live-expiration </span></td>
 <td>Number of seconds before a region or an entry expires. If timeout is not specified, it defaults to zero (which means no expiration).</td>
 <td>-1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-region-time-to-live-expiration-action</span></td>
 <td>Action that should take place when a region or an entry expires.
 <div class="p">
 Select one of the following expiration actions:
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">local-destroy</span></td>
 <td>Removes the region or entry from the local cache, but does not distribute the removal operation to remote members. You cannot use this action on partitioned region entries.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">destroy</span></td>
 <td>Removes the region or entry completely from the cache. Destroy actions are distributed according to the region's distribution settings. Use this option when the region or entry is no longer needed for any application in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword option">invalidate</span></td>
 <td>Default expiration action. Marks an entry or all entries in the region as invalid. Distributes the invalidation according to the region's scope. This is the proper choice when the region or the entry is no longer valid for any application in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword option">local-invalidate</span></td>
 <td>Marks an entry or all entries in the region as invalid but does not distribute the operation. You cannot use this action on partitioned region entries. Local region invalidation is only supported for regions that are not configured as replicated regions.</td>
 </tr>
@@ -463,78 +463,78 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-members</span></td>
 <td>Name or ID of the member(s) whose configuration is to be altered at runtime. If you do not specify this parameter, the configuration properties are modified for all cluster members using the cluster configuration service.</td>
 <td>If not specified, all members using the cluster configuration service</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>Name of the group(s) whose members's runtime configuration is to be altered. If you do not specify this parameter, the configuration properties are modified for all cluster members using the cluster configuration service.</td>
 <td>If not specified, all members using the cluster configuration service</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-archive-disk-space-limit</span></td>
 <td>Archive disk space limit. Maximum size (in megabytes) of all inactive statistic archive files combined. If this limit is exceeded, inactive archive files are deleted, oldest first, until the total size is within the limit. If set to zero, disk space use is unlimited. Valid values are (in megabytes): 0 - 1000000.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-archive-file-size-limit</span></td>
 <td>Archive file size limit. The maximum size (in megabytes) of a single statistic archive file. Once this limit is exceeded, a new statistic archive file is created, and the current archive file becomes inactive. If set to zero, file size is unlimited. Valid values are (in megabytes): 0 - 1000000.</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-log-disk-space-limit </span></td>
 <td>Log disk space limit. Maximum size in megabytes of all inactive log files combined. If this limit is exceeded, inactive log files are deleted, oldest first, until the total size is within the limit. If set to zero, disk space use is unlimited. Valid values are (in megabytes): 0 - 1000000.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-log-file-size-limit</span></td>
 <td>Log file size limit. Maximum size in megabytes of a log file before it is closed and logging rolls on to a new (child) log file. If set to zero, log rolling is disabled. Valid values are (in megabytes): 0 - 1000000.</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-loglevel </span></td>
 <td>The new log level. This option is required and you must specify a value.
 Valid values are: `ALL`, `TRACE`, `DEBUG`, `INFO`, `WARN`, `ERROR`, `FATAL`, `OFF`. 
 <td>INFO</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-statistic-archive-file </span></td>
 <td>The file to which the running system member writes statistic samples. For example: &quot;StatisticsArchiveFile.gfs&quot;. Must be defined to store the archiving to a file. Adding the <code>.gz</code> suffix to the file name causes it to be compressed. See <a href="../../../managing/statistics/chapter_overview.html">Statistics</a>.</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-statistic-sample-rate </span></td>
 <td>Statistic sampling rate. Valid values are (in milliseconds): 100 - 60000. See <a href="../../../managing/statistics/chapter_overview.html">Statistics</a>.</td>
 <td>1000</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-statistics</span></td>
 <td>Whether statistic sampling should be enabled. Specify <code>--statistic-archive-file</code> to store the statistics to a file. Valid values are: <code class="ph codeph">true</code> and <code class="ph codeph">false</code>. See <a href="../../../managing/statistics/chapter_overview.html">Statistics</a>.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-copy-on-read</span></td>
 <td>True or false. Sets the &quot;copy on read&quot; feature for cache read operations. See <a href="../../../basic_config/data_entries_custom_classes/managing_data_entries.html#managing_data_entries__section_A0E0F889AC344EFA8DF304FD64418809">Safe Entry Modification</a>.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-lock-lease</span></td>
 <td>Sets the length, in seconds, of distributed lock leases obtained by this cache. See <a href="../../../managing/monitor_tune/performance_controls_setting_cache_timeouts.html#perf">Setting Cache Timeouts</a>.</td>
 <td>120</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-lock-timeout</span></td>
 <td>Sets the number of seconds a cache operation may wait to obtain a distributed lock lease before timing out.  See <a href="../../../managing/monitor_tune/performance_controls_setting_cache_timeouts.html#perf">Setting Cache Timeouts</a>.</td>
 <td>60</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-message-sync-interval</span></td>
 <td>Sets the frequency (in seconds) at which a message will be sent by the primary cache-server node to all the secondary cache-server nodes to remove the events which have already been dispatched from the queue. See <a href="../../../developing/events/ha_event_messaging_whats_next.html#ha_event_messaging_whats_next__section_741052B413F24F47A14F5B7D7955F0AA">Change Server Queue Synchronization Frequency</a>.</td>
 <td>1</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-search-timeout</span></td>
 <td>Sets the number of seconds a cache get operation can spend searching for a value. See <a href="../../../managing/monitor_tune/performance_controls_setting_cache_timeouts.html#perf">Setting Cache Timeouts</a>.</td>
 <td>300</td>
diff --git a/geode-docs/tools_modules/gfsh/command-pages/backup.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/backup.html.md.erb
index 4cea2c2..337fd13 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/backup.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/backup.html.md.erb
@@ -50,11 +50,11 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-dir</span></td>
 <td><em>Required.</em> Directory to which backup files are written.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-baseline-dir</span></td>
 <td>Directory that contains the baseline backup used for comparison during an incremental backup.
 <p>An incremental backup operation backs up any data that is not present in the directory specified in <span class="keyword parmname">\-\-baseline-dir</span>. If the member cannot find previously backed up data or if the previously backed up data is corrupt, the command performs a full backup on that member.</p></td>
diff --git a/geode-docs/tools_modules/gfsh/command-pages/change.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/change.html.md.erb
index 684f3a9..50ad246 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/change.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/change.html.md.erb
@@ -47,17 +47,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-members</span></td>
 <td>Name or ID of one or more member(s) whose logging level you want to change.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>One or more group names. The logging level changes for all members of these groups.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-loglevel</span></td>
 <td><em>Required.</em> Log level to change. Valid options are:
  <code>ALL</code>, <code>TRACE</code>, <code>DEBUG</code>, <code>INFO</code>, <code>WARN</code>, <code>ERROR</code>, <code>FATAL</code>, <code>OFF</code>. 
diff --git a/geode-docs/tools_modules/gfsh/command-pages/connect.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/connect.html.md.erb
index 6c75a65..a3df766 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/connect.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/connect.html.md.erb
@@ -59,17 +59,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-locator</span></td>
 <td>Network address of the Locator in the form: <code class="ph codeph">host[port]</code>.</td>
 <td><code class="ph codeph">localhost[10334]</code></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-jmx-manager </span></td>
 <td>Network address of the JMX manager in the form: <code class="ph codeph">host[port]</code>.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-use-http</span></td>
 <td>Connects to a JMX manager HTTP service using the HTTP protocol.</td>
 <td><ul>
@@ -77,12 +77,12 @@
 <li>If the parameter is specified without a value: <code class="ph codeph">true</code></li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-url</span></td>
 <td>URL used to connect to a JMX manager's HTTP service</td>
 <td><code class="ph codeph">http://localhost:8080/gemfire/v1</code></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-user</span></td>
 <td>The user name of the credential to use in authentication when connecting
 to the JMX manager.
@@ -90,49 +90,49 @@
 <code>gfsh</code> will prompt for the password.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-password</span></td>
 <td>The password portion of the credential to use in authentication 
 when connecting to the JMX manager.
 </td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-key-store</span></td>
 <td>Java keystore file containing this application's certificate and private key. If the<code class="ph codeph">                                         --key-store-password</code> parameter is not specified, gfsh prompts the operator for the password.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-key-store-password</span></td>
 <td>Password to access the private key from the keystore file specified by <code class="ph codeph">--key-store</code>.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-trust-store</span></td>
 <td>Java keystore file containing the collection of CA certificates trusted by this application. If the <code class="ph codeph">--trust-store-password</code> parameter is not specified, gfsh prompts the operator for the password.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-trust-store-password</span></td>
 <td>Password to unlock the keystore file specified by <code class="ph codeph">--trust-store</code>.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-ciphers</span></td>
 <td>SSL/TLS ciphers used when encrypting the connection. The default is &quot;any&quot;.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-protocols</span></td>
 <td>SSL/TLS protocol versions to enable when encrypting the connection. The default is &quot;any&quot;.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-security-properties-file</span></td>
 <td>The <code class="ph codeph">gfsecurity.properties</code> file for configuring gfsh to connect to the Locator/Manager. The file path can be absolute or relative to the current gfsh directory.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-use-ssl</span></td>
 <td>Whether to use SSL for communication with Locator and/or JMX Manager. If set to <code class="ph codeph">true</code>, the connect command also reads <code class="ph codeph">gfsecurity.properties</code>. SSL Options take precedence over values set in the properties file. If none are specified, defaults are used.</td>
 <td><ul>
@@ -140,7 +140,7 @@
 <li>If the parameter is specified without a value: <code class="ph codeph">true</code></li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-skip-ssl-validation</span></td>
 <td>When SSL communication is enabled and this option is specified or assigned the value <code>true</code>, this gfsh client accepts any SSL certificate, allowing this gfsh client to authenticate any locator or server to which it is connecting. This option exists to facilitate testing, and it is not intended for production systems.</td>
 <td>
diff --git a/geode-docs/tools_modules/gfsh/command-pages/create.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/create.html.md.erb
index a3aac44..850f1a0 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/create.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/create.html.md.erb
@@ -94,94 +94,94 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-id</span></td>
 <td><em>Required</em>. ID of the asynchronous event queue</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>The queue is created on all members of the group(s). If you do not specify a group, the queue is created on all members.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-parallel</span></td>
 <td>Specifies whether the queue is parallel.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-batch-conflation</span></td>
 <td>Enables batch conflation.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-batch-size</span></td>
 <td>Maximum number of messages that a batch can contain.</td>
 <td>100</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-batch-time-interval</span></td>
 <td>Maximum amount of time, in ms, that can elapse before a batch is delivered.</td>
 <td>5</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-persistent</span></td>
 <td>Boolean value that determines whether <%=vars.product_name%> persists this queue.</td>
 <td>false
 <p>If specified with out a value, default is true.</p></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-disk-store</span></td>
 <td>Named disk store to use for storing queue overflow, or for persisting the queue. If you specify a value, the named disk store must exist. If you specify a null value, <%=vars.product_name%> uses the default disk store for overflow and queue persistence.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-disk-synchronous</span></td>
 <td>Specifies whether disk writes are synchronous.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-max-queue-memory</span></td>
 <td>Maximum amount of memory in megabytes that the queue can consume before overflowing to disk.</td>
 <td>100</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-dispatcher-threads</span></td>
 <td>Number of threads used for sending events.</td>
 <td>5</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-order-policy</span></td>
 <td>Policy for dispatching events when \-\-dispatcher-threads is &gt; 1. Possible values are <code class="ph codeph">THREAD</code>, <code class="ph codeph">KEY</code>, <code class="ph codeph">PARTITION</code>.</td>
 <td>KEY</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-gateway-event-filter</span></td>
 <td>List of fully qualified class names of GatewayEventFilters for this queue. These classes filter events before dispatching to remote servers.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-gateway-event-substitution-filter</span></td>
 <td>Fully-qualified class name of the <code class="ph codeph">GatewayEventSubstitutionFilter</code> for this queue.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-listener</span></td>
 <td><em>Required.</em> Fully-qualified class name of Async Event Listener for this queue</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-listener-param</span></td>
 <td>Parameter name and value to be passed to the Async Event Listener class. Optionally, you can specify a value by following the parameter name with the # character and the value. For example:
 <pre class="pre codeblock"><code>--listener-param=myParam#24</code></pre></td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-forward-expiration-destroy</span></td>
 <td>Enables forwarding of expiration destroy operations to AsyncEventListener instances. If specified without a value, this parameter is set to “false”.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-pause-event-processing</span></td>
 <td>Specifies whether event dispatching from the queue to the listener(s) will be paused when the AsyncEventQueue is started. If specified without a value, this parameter is set to "true".</td>
 <td>false</td>
@@ -275,12 +275,12 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-name</span></td>
 <td><em>Required.</em> The name of this disk store.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-dir</span></td>
 <td><em>Required.</em> One or more directory names where the disk store files are written. Optionally, directory names may be followed by <code class="ph codeph">#</code> and the maximum number of megabytes that the disk store can use in the directory. For example:
 <pre class="pre codeblock"><code>--dir=/data/ds1 
@@ -288,53 +288,53 @@
 If the specified directory does not exist, the command will create the directory for you.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-allow-force-compaction</span></td>
 <td>Set to true to allow disk compaction to be forced on this disk store.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-auto-compact</span></td>
 <td>Set to true to automatically compact the disk files.</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-compaction-threshold</span></td>
 <td>Percentage of garbage allowed before the disk store is eligible for compaction.</td>
 <td>50</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-max-oplog-size</span></td>
 <td>Maximum size, in megabytes, for an oplog file. When the oplog file reaches this size, the file is rolled over to a new file.</td>
 <td>1024</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-queue-size</span></td>
 <td>Maximum number of operations that can be asynchronously queued to be written to disk.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-time-interval</span></td>
 <td>The number of milliseconds that can elapse before unwritten data is written to disk.</td>
 <td>1000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname"> --groups</span></td>
 <td>The disk store is created on all members of the group(s). If no group is specified, the disk store is created on all members.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-write-buffer-size</span></td>
 <td>The size of the write buffer that this disk store uses when writing data to disk. Larger values may increase performance but use more memory. The disk store allocates one direct memory buffer of this size.</td>
 <td>32768</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-disk-usage-warning-percentage</span></td>
 <td>Disk usage above this threshold generates a warning message. For example, if the threshold is set to 90%, then on a 1 TB drive falling under 100 GB of free disk space generates the warning.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
 <td>90</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-disk-usage-critical-percentage</span></td>
 <td>Disk usage above this threshold generates an error message and shuts down the member's cache. For example, if the threshold is set to 99%, then falling under 10 GB of free disk space on a 1 TB drive generates the error and shuts down the cache.
 <p>Set to &quot;0&quot; (zero) to disable.</p></td>
@@ -402,12 +402,12 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>Gateway receivers are created on the members of the group(s).</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-members</span></td>
 <td>Name of the member(s) on which to create the gateway receiver.
 For backward compatibility, no gateway receiver configuration is persisted
@@ -415,49 +415,49 @@
 </td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-manual-start</span></td>
 <td>Boolean value that specifies whether you need to manually start the gateway receiver. If you specify this option without a value, the default is &quot;true&quot; the gateway receiver must be started manually.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-start-port</span></td>
 <td><p>Starting port number to use when specifying the range of possible port numbers this gateway receiver will use to connects to gateway senders in other sites. <%=vars.product_name%> chooses an unused port number in the specified port number range to start the receiver. If no port numbers in the range are available, an exception is thrown.</p>
 <p>The <code class="ph codeph">STARTPORT</code> value is inclusive while the <code class="ph codeph">ENDPORT</code> value is exclusive. For example, if you specify <code class="ph codeph">STARTPORT=&quot;50510&quot;</code> and <code class="ph codeph">ENDPORT=&quot;50520&quot;</code>, <%=vars.product_name%> chooses a port value from 50510 to 50519.</p></td>
 <td>5000</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-end-port</span></td>
 <td><p>Defines the upper bound port number to use when specifying the range of possible port numbers this gateway receiver will use to for connections from gateway senders in other sites. <%=vars.product_name%> chooses an unused port number in the specified port number range to start the receiver. If no port numbers in the range are available, an exception is thrown.</p>
 <p>The <code class="ph codeph">ENDPORT</code> value is exclusive while the <code class="ph codeph">STARTPORT</code> value is inclusive. For example, if you specify <code class="ph codeph">STARTPORT=&quot;50510&quot;</code> and <code class="ph codeph">ENDPORT=&quot;50520&quot;</code>, <%=vars.product_name%> chooses a port value from 50510 to 50519.</p></td>
 <td>5500</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-bind-address</span></td>
 <td>Network address for connections from gateway senders in other sites. Specify the address as a literal string value.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-socket-buffer-size</span></td>
 <td>An integer value that sets the buffer size (in bytes) of the socket connection for this gateway receiver. This value should match the <code class="ph codeph">socket-buffer-size</code> setting of gateway senders that connect to this receiver.</td>
 <td>32768</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-gateway-transport-filter</span></td>
 <td>The fully qualified class name of the GatewayTransportFilter to be added to the Gateway receiver.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-maximum-time-between-pings</span></td>
 <td>Integer value that specifies the time interval (in milliseconds) to use between pings to connected WAN sites. This value determines the maximum amount of time that can elapse before a remote WAN site is considered offline.</td>
 <td>60000</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-hostname-for-senders</span></td>
 <td>The host name or IP address told to gateway senders as the address for them to connect to. The locator informs gateway senders of this value.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-if-not-exists</span></td>
 <td>When specified without providing a boolean value or when specified and set to true, gateway receivers will not be created if they already exist. Command output reports the status of each creation attempt.
 </td>
@@ -522,92 +522,92 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-id</span></td>
 <td><em>Required.</em> Unique identifier for the gateway sender, usually an identifier associated with a physical location.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-remote-distributed-system-id</span></td>
 <td><em>Required.</em> ID of the remote cluster where this gateway sender sends events.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>Gateway senders are created on the members of the group(s).</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-members</span></td>
 <td>Name of the member(s) on which to create the gateway sender.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-parallel</span></td>
 <td>When set to true, specifies a parallel Gateway Sender.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-batch-conflation</span></td>
 <td>Boolean value that determines whether <%=vars.product_name%> should conflate messages.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-manual-start</span></td>
 <td><b>Deprecated.</b> Boolean value that specifies whether you need to manually start the gateway sender. If you supply a null value, the default value of false is used, and the gateway sender starts automatically. <em>A manual start is likely to cause data loss, so manual start should never be used in a production system.</em></td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-socket-buffer-size</span></td>
 <td>Size of the socket buffer that sends messages to remote sites. This size should match the size of the <code class="ph codeph">socket-buffer-size</code> attribute of remote gateway receivers that process region events.</td>
 <td>32768</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-socket-read-timeout</span></td>
 <td>Amount of time in milliseconds that the gateway sender will wait to receive an acknowledgment from a remote site. By default this is set to 0, which means there is no timeout. If you do set this timeout, you must set it to a minimum of 30000 (milliseconds). Setting it to a lower number will generate an error message and reset the value to the default of 0.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-batch-size</span></td>
 <td>Maximum number of messages that a batch can contain.</td>
 <td>100</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-batch-time-interval</span></td>
 <td>Maximum number of milliseconds that can elapse between sending batches.</td>
 <td>1000</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-persistence</span></td>
 <td>Boolean value that determines whether <%=vars.product_name%> persists the gateway queue.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-disk-store-name</span></td>
 <td>Named disk store to use for storing the queue overflow, or for persisting the queue. If you specify a value, the named disk store must exist. If you specify a null value, <%=vars.product_name%> uses the default disk store for overflow and queue persistence.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-disk-synchronous</span></td>
 <td>For regions that write to disk, boolean that specifies whether disk writes are done synchronously for the region.</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-maximum-queue-memory</span></td>
 <td>Maximum amount of memory in megabytes that the queue can consume before overflowing to disk.</td>
 <td>100 MB</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-alert-threshold</span></td>
 <td>Maximum number of milliseconds that a region event can remain in the gateway sender queue before <%=vars.product_name%> logs an alert.</td>
 <td>0</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-dispatcher-threads</span></td>
 <td>Number of dispatcher threads that are used to process region events from a gateway sender queue or asynchronous event queue.</td>
 <td>5</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-order-policy</span></td>
 <td>When the <code class="ph codeph">dispatcher-threads</code> attribute is greater than 1, <code class="ph codeph">order-policy</code> configures the way in which multiple dispatcher threads process region events from a serial gateway queue or serial asynchronous event queue. This attribute can have one of the following values:
 <dt><b>key</b></dt>
@@ -620,13 +620,13 @@
 <p>You cannot configure the <code class="ph codeph">order-policy</code> for a parallel event queue, because parallel queues cannot preserve event ordering for regions. Only the ordering of events for a given partition (or in a given queue of a distributed region) can be preserved.</p></td>
 <td>key</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-gateway-event-filter</span></td>
 <td>A list of fully-qualified class names of GatewayEventFilters (separated by commas) to be associated with the GatewaySender. This serves as a callback for users to filter out events before dispatching to a remote cluster. For example:
 <pre class="pre codeblock"><code>gateway-event-filter=com.user.filters.MyFilter1,com.user.filters.MyFilters2</code></pre></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-gateway-transport-filter</span></td>
 <td>The fully-qualified class name of the GatewayTransportFilter to be added to the GatewaySender.</td>
 <td> </td>
@@ -856,204 +856,204 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-name</span></td>
 <td><em>Required.</em> Name/Path of the region to be created.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-type</span></td>
 <td><em>Required</em> (if template-region is not specified.) Type of region to create. Options include: PARTITION, PARTITION_REDUNDANT, REPLICATE, LOCAL, etc.
 <p>To get a list of of all region type options, add the <span class="keyword parmname">\-\-type</span> parameter and then select the TAB key to display a full list.</p></td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-template-region </span></td>
 <td><em>Required</em> (if type is not specified.) Name/Path of the region whose attributes should be duplicated when creating this region.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>Group(s) of members on which the region will be created.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-if-not-exists</span></td>
 <td>A new region will not be created if a region with the same name already exists. By default, an attempt to create a duplicate region is reported as an error.
 If this option is specified without a value or is specified with a value of <code>true</code>, then gfsh displays a "Skipping..." acknowledgement, but does not throw an error.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-key-constraint</span></td>
 <td>Fully qualified class name of the objects allowed as region keys. Ensures that keys for region entries are all of the same class.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-value-constraint </span></td>
 <td>Fully qualified class name of the objects allowed as region values. If not specified, then region values can be of any class.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-statistics</span></td>
 <td>Whether to gather statistics for the region. Must be true to use expiration on the region.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-idle-time-expiration</span></td>
 <td>How long, in seconds, the region's entries can remain in the cache without being accessed.</td>
 <td>no expiration</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-entry-idle-time-expiration-action </span></td>
 <td>Action to be taken on an entry that has exceeded the idle expiration. Valid expiration actions include destroy, local-destroy, invalidate (default), local-invalidate.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-time-to-live-expiration</span></td>
 <td>How long, in seconds, the region's entries can remain in the cache without being accessed or updated. The default is no expiration of this type.</td>
 <td>no expiration</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-entry-time-to-live-expiration-action</span></td>
 <td>Action to be taken on an entry that has exceeded the TTL expiration. Valid expiration actions include destroy, local-destroy, invalidate (default), local-invalidate.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-idle-time-custom-expiry</span></td>
 <td>The name of a class implementing CustomExpiry for entry idle time. Append a JSON string for initialization properties.</td>
 <td></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-entry-time-to-live-custom-expiry</span></td>
 <td>The name of a class implementing CustomExpiry for entry time to live. Append a JSON string for initialization properties.</td>
 <td></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-region-idle-time-expiration</span></td>
 <td>How long, in seconds, the region can remain in the cache without its entries being accessed. The default is no expiration of this type.</td>
 <td></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-region-idle-time-expiration-action</span></td>
 <td>Action to be taken on a region that has exceeded the idle expiration. Valid expiration actions include destroy, local-destroy, invalidate (default), local-invalidate. The destroy and local-destroy actions destroy the region. The invalidate and local-invalidate actions leave the region in place, but invalidate all of its entries.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-region-time-to-live-expiration</span></td>
 <td>How long, in seconds, the region can remain in the cache without its entries being accessed or updated. The default is no expiration of this type.</td>
 <td>no expiration</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-region-time-to-live-expiration-action</span></td>
 <td>Action to be taken on a region that has exceeded the TTL expiration. Valid expiration actions include destroy, local-destroy, invalidate (default), local-invalidate. The destroy and local-destroy actions destroy the region. The invalidate and local-invalidate actions leave the region in place, but invalidate all of its entries.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-disk-store</span></td>
 <td>Disk Store to be used by this region. The <a href="list.html#topic_BC14AD57EA304FB3845766898D01BD04">list disk-stores</a> command can be used to display existing disk stores.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-synchronous-disk</span></td>
 <td>Whether writes are done synchronously for regions that persist data to disk.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-enable-async-conflation</span></td>
 <td>Whether to allow aggregation of asynchronous TCP/IP messages sent by the producer member of the region. A false value causes all asynchronous messages to be sent individually.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-subscription-conflation</span></td>
 <td>Whether the server should conflate its messages to the client. A false value causes all server-client messages to be sent individually.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-cache-listener</span></td>
 <td>Fully qualified class name of a plug-in to be instantiated for receiving after-event notification of changes to the region and its entries. Any number of cache listeners can be configured. A fully qualified class name may be appended with a JSON specification that will be parsed to become the fields of the parameter to the <code>init()</code> method for a class that implements the <code>Declarable</code> interface.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-cache-loader</span></td>
 <td>Fully qualified class name of a plug-in to be instantiated for receiving notification of cache misses in the region. At most, one cache loader can be defined in each member for the region. For distributed regions, a cache loader may be invoked remotely from other members that have the region defined. A fully qualified class name may be appended with a JSON specification that will be parsed to become the fields of the parameter to the <code>initialize()</code> method for a class that implements the <code>Declarable</code> interface.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-cache-writer</span></td>
 <td>Fully qualified class name of a plug-in to be instantiated for receiving before-event notification of changes to the region and its entries. The plug-in may cancel the event. At most, one cache writer can be defined in each member for the region. A fully qualified class name may be appended with a JSON specification that will be parsed to become the fields of the parameter to the <code>init()</code> method for a class that implements the <code>Declarable</code> interface.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-async-event-queue-id</span></td>
 <td>IDs of the Async Event Queues that will be used for write-behind operations.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-gateway-sender-id</span></td>
 <td>IDs of the Gateway Senders to which data will be routed.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-enable-concurrency-checks</span></td>
 <td>Whether Region Version Vectors are implemented. Region Version Vectors are an extension to the versioning scheme that aid in synchronization of replicated regions.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-enable-cloning</span></td>
 <td>Determines how fromDelta applies deltas to the local cache for delta propagation. When true, the updates are applied to a clone of the value and then the clone is saved to the cache. When false, the value is modified in place in the cache.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-concurrency-level </span></td>
 <td>Estimate of the maximum number of application threads that will concurrently access a region entry at one time. This attribute does not apply to partitioned regions.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-colocated-with </span></td>
 <td>Central Region with which this region should be colocated.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-local-max-memory</span></td>
 <td>Maximum amount of memory, in megabytes, to be used by the region in this process. (The default is 90% of available heap.)</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-recovery-delay </span></td>
 <td>Delay in milliseconds that existing members will wait after a member crashes before restoring this region's redundancy on the remaining members. The default value (-1) indicates that redundancy will not be recovered after a failure.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-redundant-copies </span></td>
 <td>Number of extra copies of buckets desired. Extra copies allow for both high availability in the face of VM departure (intended or unintended) and load balancing read operations. (Allowed values: 0, 1, 2 and 3)</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-startup-recovery-delay </span></td>
 <td>Delay in milliseconds that new members will wait before assuming their share of cluster-level redundancy. This allows time for multiple regions to start before the redundancy workload is parceled out to the new members. A value of -1 indicates that adding new members will not trigger redundancy recovery.</td>
 <td>The default is to recover redundancy immediately when a new member is added.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-total-max-memory </span></td>
 <td>Maximum amount of memory, in megabytes, to be used by the region in all processes.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-total-num-buckets </span></td>
 <td>Total number of hash buckets to be used by the region in all processes.</td>
 <td>113</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-compressor</span></td>
 <td>Java class name that implements compression for the region. You can write a custom compressor that implements <code class="ph codeph">org.apache.geode.compression.Compressor</code> or you can specify the Snappy compressor (<code class="ph codeph">org.apache.geode.compression.SnappyCompressor</code>), which is bundled with <%=vars.product_name%>. See <a href="../../../managing/region_compression.html">Region Compression</a>.</td>
 <td>no compression</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-off-heap</span></td>
 <td>Specifies whether the region values are stored in heap memory or off-heap memory. When true, region values are in off-heap memory. If the parameter is specified without a value, the value of true is used.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-partition-resolver</span></td>
 <td>Specifies the full path to a custom partition resolver. Specify <code class="ph codeph">org.apache.geode.cache.util.StringPrefixPartitionResolver</code> to use the included string prefix partition resolver.</td>
 <td></td>
@@ -1074,11 +1074,11 @@
 <div class="p">
 <table>
 <tbody>
-<tr class="odd">
+<tr>
 <td>local-destroy</td>
 <td>Entry is destroyed locally. Use with caution - may lead to inconsistencies.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>overflow-to-disk</td>
 <td>Entry is overflowed to disk. For partitioned regions, this provides the most reliable read behavior across the region.</td>
 </tr>
diff --git a/geode-docs/tools_modules/gfsh/command-pages/run.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/run.html.md.erb
index 9b07ae6..5d445350 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/run.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/run.html.md.erb
@@ -51,12 +51,12 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-file</span></td>
 <td><em>Required.</em> Path of the file scripted with commands that <code class="ph codeph">gfsh</code> recognizes. Path should be relative or absolute.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-quiet</span></td>
 <td>Specifies whether to show command output.
 <div class="note note">
@@ -65,7 +65,7 @@
 </div></td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-continue-on-error</span></td>
 <td>Specifies whether further execution of the script should continue if there is an error while executing one of the commands fails.</td>
 <td>false</td>
diff --git a/geode-docs/tools_modules/gfsh/command-pages/show.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/show.html.md.erb
index fb0b1b0..f9b1a40 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/show.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/show.html.md.erb
@@ -151,23 +151,23 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-member</span></td>
 <td>Name/ID of the member whose metrics will be displayed/exported.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-region</span></td>
 <td>Name/Path of the region whose metrics will be displayed/exported.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-file</span></td>
 <td>Name of the file to which metrics will be written.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-port</span></td>
 <td>Port number of the Cache Server whose metrics are to be displayed/exported. This can only be used along with the <code class="ph codeph">--member</code> parameter.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-categories</span></td>
 <td>Categories available based upon the parameters specified (listed above) are:
 <ul>
diff --git a/geode-docs/tools_modules/gfsh/command-pages/start.html.md.erb b/geode-docs/tools_modules/gfsh/command-pages/start.html.md.erb
index d1cb925..165257e 100644
--- a/geode-docs/tools_modules/gfsh/command-pages/start.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/command-pages/start.html.md.erb
@@ -265,7 +265,7 @@
 
 ``` pre
 start locator --name=value [--bind-address=value] [--force(=value)]
- [--groups=value(,value)*] [--hostname-for-clients=value]
+ [--groups=value(,value)*] [--hostname-for-clients=value] [--classpath=value]
  [--locators=value] [--log-level=value] [--mcast-address=value] [--mcast-port=value] [--port=value] [--dir=value]
  [--properties-file=value] [--security-properties-file=value] [--initial-heap=value] [--max-heap=value]
  [--connect(=value)] [--enable-cluster-configuration(=value)] [--load-cluster-configuration-from-dir(=value)]
@@ -290,72 +290,77 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-name</span></td>
 <td>Name to be used for this <%=vars.product_name%> locator service. If not specified, gfsh generates a random name.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-bind-address</span></td>
 <td>IP address on which the locator will be bound.</td>
 <td>bind to all addresses</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-force</span></td>
 <td>Whether to allow the PID file from a previous locator run to be overwritten.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>Group(s) the locator will be a part of.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-hostname-for-clients</span></td>
 <td>Host name or IP address that will be sent to clients so they can connect to this locator.</td>
 <td>uses <code>bind-address</code></td>
 </tr>
-<tr class="even">
+<tr>
+<td><span class="keyword parmname">\-\-classpath</span></td>
+<td>Application classes to be added to the locator's CLASSPATH after the core jar file. See <a href="../../../getting_started/setup_classpath.html">Setting Up the CLASSPATH</a> for details.</td>
+<td> </td>
+</tr>
+<tr>
 <td><span class="keyword parmname">\-\-locators</span></td>
 <td>List of locators used by this locator to join the appropriate <%=vars.product_name%> cluster.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-log-level</span></td>
 <td>Level of output logged to the locator log file. Possible values for log-level include: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-mcast-address </span></td>
 <td>IP address or hostname used to bind the UPD socket for multi-cast networking so the locator can locate other members in the <%=vars.product_name%> cluster. If mcast-port is zero, then mcast-address is ignored.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-mcast-port</span></td>
 <td>Port used for multi-cast networking so the locator can locate other members of the <%=vars.product_name%> cluster. A zero value disables mcast.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-port</span></td>
 <td>Port the locator will listen on.</td>
 <td>10334</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-dir</span></td>
 <td>Directory in which the Locator will be started and run.</td>
 <td><span class="ph filepath">./&lt;locator-member-name&gt;</span></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-properties-file</span></td>
 <td>Specify the <code class="ph codeph">gemfire.properties</code> file for configuring the locator's cluster. The file's path should be absolute or relative to gfsh's working directory.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-security-properties-file</span></td>
 <td>The <span class="ph filepath">gfsecurity.properties</span> file for configuring the Locator's security configuration in the cluster. The file's path can be absolute or relative to gfsh's working directory.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-initial-heap</span></td>
 <td>Size has the same format as the <code class="ph codeph">-Xmx</code>/<code class="ph codeph">-Xms</code> JVM options.
 <div class="note note">
@@ -363,7 +368,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-max-heap</span></td>
 <td>Size has the same format as the <code class="ph codeph">-Xmx</code>/<code class="ph codeph">-Xms</code> JVM options
 <div class="note note">
@@ -372,44 +377,44 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-connect</span></td>
 <td>When connect is set to false, gfsh does not automatically connect to the locator which is started using this command.</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-enable-cluster-configuration</span></td>
 <td>Enables cluster configuration behavior where locators maintain configurations for all members of the cluster. 
 See <a href="../../../configuring/cluster_config/gfsh_persist.html">Overview of the Cluster Configuration Service</a>.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-load-cluster-configuration-from-dir</span></td>
 <td><b>Deprecated. Use <code>gfsh import cluster-configuration</code> for this functionality.</b> Loads the cluster configuration from the <span class="ph filepath">shared-config</span> directory. (When set to false, the configuration is loaded from the disk store of the internal, persistent region used by the locator to persist the configuration.)</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-cluster-config-dir</span></td>
 <td>Directory used by the cluster configuration service to store the cluster configuration on the filesystem</td>
 <td>cluster-config</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-redirect-output</span></td>
 <td>When true, redirect standard output and standard error to the locator log file. If specified without a value, the value is set to true.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-http-service-port</span></td>
 <td>Specifies the HTTP service port.</td>
 <td>7070</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-http-service-bind-address</span></td>
 <td>Specifies the IP address to which the HTTP service will be bound.
 </td>
 <td>the local host machine's address</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-J </span></td>
 <td>Argument passed to the JVM on which the Locator will run. For example, specifying <code class="ph codeph">--J=-Dfoo.bar=true</code> sets property &quot;foo.bar&quot; to &quot;true&quot;.
 <div class="note note">
@@ -508,138 +513,138 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-name</span></td>
 <td>Member name for this server. If not specified, gfsh generates a random name.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-assign-buckets</span></td>
 <td>Whether to assign buckets to the partitioned regions of the cache on server start.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-bind-address</span></td>
 <td>The IP address on which the server will be bound.</td>
 <td>binds to all local addresses</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-cache-xml-file</span></td>
 <td>Specifies the name of the XML file or resource to initialize the cache with when it is created.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-classpath</span></td>
-<td>Application classes added to the server's CLASSPATH after the core jar file. See <a href="../../../getting_started/setup_classpath.html">Setting Up the CLASSPATH</a> for details.</td>
+<td>Application classes to be added to the server's CLASSPATH after the core jar file. See <a href="../../../getting_started/setup_classpath.html">Setting Up the CLASSPATH</a> for details.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-include-system-classpath</span></td>
 <td>When true, include the System CLASSPATH on the Server's CLASSPATH, as the System CLASSPATH is not included by default. If specified without a value, the value is set to true.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-disable-default-server</span></td>
 <td>Whether the cache server will be started by default. If the parameter is specified without a value, the value is set to true. If set to true, the cache server acts as a peer.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-disable-exit-when-out-of-memory</span></td>
 <td>Prevents the JVM from exiting when an OutOfMemoryError occurs.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-enable-time-statistics</span></td>
 <td>Causes additional time-based statistics to be gathered for <%=vars.product_name%> operations.</td>
 <td>true</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-properties-file</span></td>
 <td>The <span class="ph filepath">gemfire.properties</span> file for configuring the server's cluster. The file's path can be absolute or relative to the gfsh working directory.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-security-properties-file</span></td>
 <td>The <span class="ph filepath">gfsecurity.properties</span> file for configuring the server's security configuration in the cluster. The file's path can be absolute or relative to gfsh directory.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-groups</span></td>
 <td>Group(s) the Cache Server will be a part of.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-force</span></td>
 <td>Whether to allow the PID file from a previous Cache Server run to be overwritten.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-locators </span></td>
 <td>Sets the list of locators used by the Cache Server to join the appropriate <%=vars.product_name%> cluster.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-locator-wait-time</span></td>
 <td>Sets the number of seconds the server will wait for a locator to become available during startup before giving up.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-log-level</span></td>
 <td>Sets the level of output logged to the Cache Server log file. Possible values for log-level include: ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-mcast-address</span></td>
 <td>The IP address or hostname used to bind the UDP socket for multi-cast networking so the Cache Server can locate other members in the <%=vars.product_name%> cluster. If mcast-port is zero, then mcast-address is ignored.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-mcast-port</span></td>
 <td>Sets the port used for multi-cast networking so the Cache Server can locate other members of the <%=vars.product_name%> cluster. A zero value disables mcast.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-memcached-port</span></td>
 <td>If specified and is non-zero, sets the port number for an embedded Gemcached server and starts the Gemcached server.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-memcached-protocol</span></td>
 <td>Sets the protocol used by an embedded Gemcached server. Valid values are <code class="ph codeph">BINARY</code> and <code class="ph codeph">ASCII.</code> If you omit this property, the ASCII protocol is used.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-server-bind-address</span></td>
 <td>Overrides the <code>bind-address</code> on which this server will listen for client connections. Set this option in a multi-homed server environment to distinguish communications from clients. Setting a value of the empty string (&quot;&quot;) uses the value of <code>bind-address</code>.</td>
 <td>value of <code>bind-address</code></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-server-port</span></td>
 <td>Port the Server will listen on for client connections.</td>
 <td>40404</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-spring-xml-location</span></td>
 <td>Specifies the location of a Spring XML configuration file(s) for bootstrapping and configuring a <%=vars.product_name%> Server. This configuration file can exist on the CLASSPATH (default) or any location supported by Spring's Resource(Loader) location specifiers (for example, classpath:, file:, etc). ResourceLoader is described in the 
 <a href="http://docs.spring.io/spring/docs/4.0.9.RELEASE/spring-framework-reference/htmlsingle/#resources-resourceloader">Spring documentation</a>.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-rebalance</span></td>
 <td>Whether to initiate rebalancing across the <%=vars.product_name%> cluster.</td>
 <td>false</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-dir</span></td>
 <td>Specify the directory in which the server will run in. This directory is written to the location where you started <code class="ph codeph">gfsh</code>.</td>
 <td>If not specified, the directory is named after the server.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-statistic-archive-file </span></td>
 <td>The file that statistic samples are written to. For example: &quot;StatisticsArchiveFile.gfs&quot;. Must be defined to store the archiving to a file. An empty string (default) disables statistic archival.</td>
 <td><em>not set</em></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-initial-heap</span></td>
 <td>Initial size of the heap in the same format as the JVM -Xms parameter.
 <div class="note note">
@@ -647,7 +652,7 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-max-heap</span></td>
 <td>Maximum size of the heap in the same format as the JVM -Xmx parameter.
 <div class="note note">
@@ -656,29 +661,29 @@
 </div></td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-J</span></td>
 <td>Argument passed to the JVM on which the Cache Server will run. For example, <code class="ph codeph">--J=-Dfoo.bar=true</code> will set the property &quot;foo.bar&quot; to &quot;true&quot;.
 <p>If the argument you are passing contains spaces or commas, enclose the option in single quotes.</p></td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-use-cluster-configuration</span></td>
 <td>Specifies whether the server requests a cluster configuration from the locator. 
 See <a href="../../../configuring/cluster_config/gfsh_persist.html">Overview of the Cluster Configuration Service</a>.</td>
 <td>true</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-critical-heap-percentage</span></td>
 <td>Set the percentage of heap at or above which the cache is considered in danger of becoming inoperable due to garbage collection pauses or out of memory exceptions. Past the threshold, operations that require heap space will throw a <code class="ph codeph">LowMemoryException</code>. This feature requires additional VM flags to perform properly; you must set <code class="ph codeph">--initial-heap</code> and <code class="ph codeph">--max-heap</code> or the corresponding JVM properties to use this threshold. You must also set <code class="ph codeph">--max-heap</code> and <code class="ph codeph">--initial-heap</code> to the same value.</td>
 <td>0 (no critical heap threshold enforced)</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-critical-off-heap-percentage</span></td>
 <td>The percentage of off-heap memory used at or above which the cache is considered in danger of becoming inoperable due to out of memory exceptions. Past the threshold, operations that require heap space will throw a <code class="ph codeph">LowMemoryException</code>.</td>
 <td>0 (no critical off-heap threshold enforced)</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-eviction-heap-percentage</span></td>
 <td>Set the percentage of heap at or above which the eviction should begin on Regions configured for HeapLRU eviction. Changing this value may cause eviction to begin immediately. Only one change to this attribute or critical heap percentage will be allowed at any given time and its effect will be fully realized before the next change is allowed. This feature requires additional VM flags to perform properly; you must set <code class="ph codeph">--initial-heap</code> and <code class="ph codeph">--max-heap</code> or the corresponding JVM properties to use this threshold. You must also set <code class="ph codeph">--max-heap</code> and <code class="ph codeph">--initial-heap</code> to the same value.</td>
 <td><ul>
@@ -687,7 +692,7 @@
 <li>80%, if <code class="ph codeph">critical-heap-percentage</code> is not configured.</li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-eviction-off-heap-percentage</span></td>
 <td>The percentage of off-heap memory used at or above which the eviction should begin on regions configured for off-heap and HeapLRU eviction. Changing this value may cause eviction to begin immediately. Only one change to this attribute or critical off-heap percentage will be allowed at any given time, and its effect will be fully realized before the next change is allowed.</td>
 <td><ul>
@@ -696,68 +701,68 @@
 <li>80%, if <code class="ph codeph">critical-off-heap-percentage</code> is not configured.</li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-hostname-for-clients</span></td>
 <td>Sets the IP address or host name that a locator will provide to clients. Clients use the address to connect to a server. Set this value when clients use a different address to connect with the server than the <code>bind-address</code>, as those clients might with servers in a private cloud or multi-homed environment. Not specifying this option or setting this option to the empty string (&quot;&quot;) causes the <code>bind-address</code> to be given to clients.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-max-connections</span></td>
 <td>Sets the maximum number of client connections allowed. When the maximum is reached the cache server will stop accepting connections</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-message-time-to-live</span></td>
 <td>Sets the time (in seconds ) after which a message in the client queue will expire.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-max-message-count</span></td>
 <td>Sets maximum number of messages that can be enqueued in a client-queue.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-max-threads</span></td>
 <td>Sets the maximum number of threads allowed in this cache server to service client requests. The default of 0 causes the cache server to dedicate a thread for every client connection.</td>
 <td> </td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-socket-buffer-size</span></td>
 <td>Sets the buffer size in bytes of the socket connection for this CacheServer. The default is 32768 bytes.</td>
 <td> </td>
 </tr>
-<tr class="odd">
+<tr>
 <td><span class="keyword parmname">\-\-lock-memory</span></td>
 <td>(Linux only) When true, the member's heap and off-heap memory are locked in RAM, preventing them from being paged to disk. You must increase the related <code class="ph codeph">ulimit</code> operating system resource to allow the OS to lock memory chunks of sufficient size.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-off-heap-memory-size</span></td>
 <td>The integer quantity of off-heap memory to be used for storing region values. Specified in Gigabytes with a 'g' suffix, or Megabytes with an 'm' suffix. For example, allocate a 2 Gigabyte off-heap space with <code class="ph codeph">--off-heap-memory-size=2g</code>. The default value of 0 does not use any off-heap memory.</td>
 <td>0</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-start-rest-api</span></td>
 <td>When true, starts the REST API service.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-redirect-output</span></td>
 <td>When true, redirect standard output and standard error to the server log file. If specified without a value, the value is set to true.</td>
 <td>false</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-http-service-port</span></td>
 <td>Specifies the HTTP service port.</td>
 <td>7070</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-http-service-bind-address</span></td>
 <td>Specifies the IP address to which the HTTP service will be bound.
 </td>
 <td>the local host machine's address</td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-user</span></td>
 <td>The user name of the credential to use in authenticating to the cluster.
 When specified, if the <code>--password</code> option is not also specified,
@@ -765,7 +770,7 @@
 </td>
 <td></td>
 </tr>
-<tr class="even">
+<tr>
 <td><span class="keyword parmname">\-\-password</span></td>
 <td>The password portion of the credential to use in authenticating to
 the cluster.
diff --git a/geode-docs/tools_modules/gfsh/quick_ref_commands_by_area.html.md.erb b/geode-docs/tools_modules/gfsh/quick_ref_commands_by_area.html.md.erb
index ba46393..ced6b8f 100644
--- a/geode-docs/tools_modules/gfsh/quick_ref_commands_by_area.html.md.erb
+++ b/geode-docs/tools_modules/gfsh/quick_ref_commands_by_area.html.md.erb
@@ -53,17 +53,17 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><a href="command-pages/alter.html#topic_7E6B7E1B972D4F418CB45354D1089C2B">alter runtime</a></td>
 <td>Alters configuration properties for a specific member or members while the member or members are running.</td>
 <td>online</td>
 </tr>
-<tr class="even">
+<tr>
 <td><a href="command-pages/change.html#topic_E74ED23CB60342538B2175C326E7D758">change loglevel</a></td>
 <td>Changes the logging level on specified servers.</td>
 <td>online</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><a href="command-pages/configure.html#topic_jdkdiqbgphqh">configure pdx</a></td>
 <td>This command alters cluster-wide PDX configuration settings for all caches.</td>
 <td>online
@@ -71,27 +71,27 @@
 **Note:** This command must be run before starting data members in order to enforce configuration settings.
 </div></td>
 </tr>
-<tr class="even">
+<tr>
 <td><a href="command-pages/describe.html#topic_3C2C817D999C4E40AF788808B7B6AF99">describe config</a></td>
 <td>Display the configuration of a member.</td>
 <td>online</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><a href="command-pages/export.html#topic_C7C69306F93743459E65D46537F4A1EE">export config</a></td>
 <td>Export configurations, data, logs and stack-traces.</td>
 <td>online</td>
 </tr>
-<tr class="even">
+<tr>
 <td><a href="command-pages/export.html#topic_mdv_jgz_ck">export cluster-configuration</a></td>
 <td>Exports a shared configuration ZIP file that contains cache.xml files, gemfire.properties files and JAR files needed to configure and operate a cluster.</td>
 <td>online</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><a href="command-pages/import.html#topic_vnv_grz_ck">import cluster-configuration</a></td>
 <td>Import an exported configuration.</td>
 <td>online</td>
 </tr>
-<tr class="even">
+<tr>
 <td><a href="command-pages/status.html#topic_ts1_qb1_dk2">status cluster-config-service</a></td>
 <td>Reports on the status of the cluster configuration server.</td>
 <td>online</td>
diff --git a/geode-docs/tools_modules/pulse/pulse-hosted.html.md.erb b/geode-docs/tools_modules/pulse/pulse-hosted.html.md.erb
index 267b1fd..36468ee 100644
--- a/geode-docs/tools_modules/pulse/pulse-hosted.html.md.erb
+++ b/geode-docs/tools_modules/pulse/pulse-hosted.html.md.erb
@@ -46,17 +46,17 @@
     </tr>
     </thead>
     <tbody>
-    <tr class="odd">
+    <tr>
     <td><code class="ph codeph">pulse.useLocator</code></td>
     <td>Specify &quot;true&quot; to configure Pulse to connect to a <%=vars.product_name%> Locator member, or &quot;false&quot; to connect directly to a JMX Manager.
     <p>When Pulse connects to a <%=vars.product_name%> locator, the locator provides the address and port of an available JMX Manager to use for monitoring the cluster. In most production deployments, you should connect Pulse to a locator instance; this allows Pulse to provide monitoring services using any available JMX Manager.</p>
     <p>If you specify &quot;false,&quot; Pulse connects directly to a specific JMX Manager. If this manager is not available, the Pulse connection fails, even if another JMX Manager is available in the cluster.</p></td>
     </tr>
-    <tr class="even">
+    <tr>
     <td><code class="ph codeph">pulse.host</code></td>
     <td>Specify the DNS name or IP address of the <%=vars.product_name%> locator or JMX Manager machine to which Pulse should connect. You specify either a locator or JMX Manager address depending on how you configured the <code class="ph codeph">pulse.useLocator</code> property.</td>
     </tr>
-    <tr class="odd">
+    <tr>
     <td><code class="ph codeph">pulse.port</code></td>
     <td>Specify the port number of the <%=vars.product_name%> locator or the HTTP port number of the JMX Manager to which Pulse should connect. You specify either a locator or JMX Manager port depending on how you configured the <code class="ph codeph">pulse.useLocator</code> property.
     <p>If you configured <code class="ph codeph">pulse.useLocator=false</code>, then <code class="ph codeph">pulse.port</code> must correspond to the <code class="ph codeph">http-service-port</code> setting of the JMX Manager.</p></td>
diff --git a/geode-docs/tools_modules/pulse/pulse-views.html.md.erb b/geode-docs/tools_modules/pulse/pulse-views.html.md.erb
index 831fa46..b9518a0 100644
--- a/geode-docs/tools_modules/pulse/pulse-views.html.md.erb
+++ b/geode-docs/tools_modules/pulse/pulse-views.html.md.erb
@@ -68,63 +68,63 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><strong>Cluster Status</strong></td>
 <td>Overall status of the cluster being monitored. Possible statuses include Normal, Warning, or Severe.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Total Heap</td>
 <td>Total amount of memory (in GB) allocated to the Java heap across all members.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Members</td>
 <td>Total number of members in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Servers</td>
 <td>Total number of servers in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Clients</td>
 <td>Total number of clients in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Locators</td>
 <td>Total number of locators in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Regions</td>
 <td>Total number of regions in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Functions</td>
 <td>Total number of functions registered in the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Unique CQs</td>
 <td>Total number of unique CQs. Corresponds to the UNIQUE _CQ_QUERY statistic.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Subscriptions</td>
 <td>Total number of client event subscriptions.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>Cluster Members</strong></td>
 <td>Graphical, block, or table view of the members in the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Topology</td>
 <td>Organizes cluster members by DistributedMember Id.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Server Groups</td>
 <td>Organizes cluster members by server group membership. If no server groups are configured, all members appear under the &quot;Default&quot; server group.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Redundancy Zones</td>
 <td>Organizes cluster members by redundancy zones. If no redundancy zones are configured, all members appear under the &quot;Default&quot; zone.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Host Machine</td>
 <td>When you mouse over a machine icon in Topology View, a pop-up appears with the following machine statistics:
 <ul>
@@ -134,7 +134,7 @@
 <li><em>Sockets</em>. Number of sockets currently open on the machine.</li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td>Member</td>
 <td>When you mouse over a member icon in Graphical View, a pop-up appears with the following member statistics:
 <ul>
@@ -148,7 +148,7 @@
 <li><em>GemFire Version</em>. The version of the <%=vars.product_name%> member.</li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Member</td>
 <td>In List View, the following data fields are displayed for each member:
 <ul>
@@ -161,35 +161,35 @@
 <li><em>Clients</em>. Number of clients currently connected to the member. It will have a value only if the member acts as a CacheServer.</li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>Key Statistics</strong></td>
 <td>Displays a few key performance measurements of the cluster (over the last 15 minutes).</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Write/Sec</td>
 <td>Number of write operations per second that have occurred across the cluster. Each put/putAll operation counts as a write; for example, a putAll of 50 entries is counted as one write.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Read/Sec</td>
 <td>Number of read operations per second that have occurred across the cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Queries/Sec</td>
 <td>Number of queries per second that have been executed across the cluster.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>No. of JVM Pauses</strong></td>
 <td>Number of times the JVM has paused during the last five minutes to perform garbage collection.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>WAN Information</strong></td>
 <td>If you have configured gateway senders or receivers for a multi-site (WAN) deployment, this box displays whether the remote cluster is reachable (working connectivity represented by a green triangle).</td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>Disk Throughput</strong></td>
 <td>Total disk throughput for all disks in cluster.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>Alerts View</strong></td>
 <td>Displays alerts for the cluster.</td>
 </tr>
@@ -225,35 +225,35 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><strong>Member Status</strong></td>
 <td>Overall status of the member being monitored. Possible statuses include Normal, Warning, or Severe.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Regions</td>
 <td>Total number of regions hosted on the member.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Threads</td>
 <td>Total number of threads being executed on the member.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Sockets</td>
 <td>Total number of sockets currently open on the member.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Load Avg.</td>
 <td>Average number of threads on the member that are in the run queue or are waiting for disk I/O over the last minute. Corresponds to the Linux System statistic loadAverage1. If the load average is not available, a negative value is shown.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Clients</td>
 <td>Current number of client connections to the member.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>Member Regions</strong></td>
 <td>Block or table view of the regions hosted on the member.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Regions</td>
 <td>When you mouse over a region in block view, a pop-up appears with the following data fields:
 <ul>
@@ -263,7 +263,7 @@
 <li><em>EntrySize</em>. The aggregate entry size (in bytes) of all entries. For replicated regions this field will only provide a value if the eviction algorithm has been set to EvictionAlgorithm#LRU_ MEMORY. All partition regions will have this value. However, the value includes redundant entries and will also count the size of all the secondary entries on the node.</li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Regions</td>
 <td>In table view, the following fields are listed for each region:
 <ul>
@@ -277,7 +277,7 @@
 <li><em>Gateway Enabled</em>. Whether gateway sender and receiver configurations have been defined on members hosting this region.</li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>Member Clients</strong></td>
 <td>In table view, the following fields are listed for each client:
 <ul>
@@ -293,35 +293,35 @@
 <li><em>Puts</em>. Total number of successful put requests completed.</li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>Key Statistics</strong></td>
 <td>Displays a few key performance measurements for the member (over the last 15 minutes).</td>
 </tr>
-<tr class="even">
+<tr>
 <td>% CPU Usage</td>
 <td>Percentage of CPU used by the member.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Read/Sec</td>
 <td>Number of read operations per second that have occurred on the member.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Write/Sec</td>
 <td>Number of write operations per second that have occurred on the member. Each put/putAll operation counts as a write; for example, a putAll of 50 entries is counted as one write.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>Memory Usage</strong></td>
 <td>Total memory used on the member in MB.</td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>No. of JVM Pauses</strong></td>
 <td>Number of times the JVM has paused during the last five minutes due to garbage collection or excessive CPU usage.</td>
 </tr>
-<tr class="odd">
+<tr>
 <td><strong>WAN Information</strong></td>
 <td>Displays cluster information. This dialog box only appears if you have configured WAN functionality (gateway senders and gateway receivers).</td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>Disk Throughput</strong></td>
 <td>Rate of disk writes on the member.</td>
 </tr>
@@ -360,11 +360,11 @@
 </tr>
 </thead>
 <tbody>
-<tr class="odd">
+<tr>
 <td><strong>Region Members</strong></td>
 <td>Lists information about <%=vars.product_name%> members that host the region, either in block view or table view.</td>
 </tr>
-<tr class="even">
+<tr>
 <td>Region Member (Detail View)</td>
 <td>When you hover over a region member in block view, a pop-up appears with the following data fields:
 <ul>
@@ -375,7 +375,7 @@
 <li><em>Reads/Writes</em>. Summary of reads and writes served from memory and from disk stores over the last 15 minutes.</li>
 </ul></td>
 </tr>
-<tr class="odd">
+<tr>
 <td>Region Member (Table View)</td>
 <td>In table view, the following fields are listed for each region member:
 <ul>
@@ -388,7 +388,7 @@
 <li><em>Accessor</em>. Indicates whether the member is an accessor member.</li>
 </ul></td>
 </tr>
-<tr class="even">
+<tr>
 <td><strong>Region Detail</strong></td>
 <td>When you have selected a region, the right hand pane displays the following information about the region:
 <ul>
diff --git a/geode-http-service/src/main/java/org/apache/geode/internal/cache/InternalHttpService.java b/geode-http-service/src/main/java/org/apache/geode/internal/cache/InternalHttpService.java
index 1d89f6f..a50b3b2 100644
--- a/geode-http-service/src/main/java/org/apache/geode/internal/cache/InternalHttpService.java
+++ b/geode-http-service/src/main/java/org/apache/geode/internal/cache/InternalHttpService.java
@@ -104,7 +104,7 @@
     httpConfig.setSecurePort(port);
 
     if (sslConfig.isEnabled()) {
-      SslContextFactory sslContextFactory = new SslContextFactory();
+      SslContextFactory sslContextFactory = new SslContextFactory.Server();
 
       if (StringUtils.isNotBlank(sslConfig.getAlias())) {
         sslContextFactory.setCertAlias(sslConfig.getAlias());
diff --git a/geode-management/src/test/script/update-management-wiki.sh b/geode-management/src/test/script/update-management-wiki.sh
new file mode 100755
index 0000000..23e33c0
--- /dev/null
+++ b/geode-management/src/test/script/update-management-wiki.sh
@@ -0,0 +1,162 @@
+#! /usr/bin/env bash
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+URI_VERSION=/experimental
+
+set -e
+
+usage() {
+    echo "Usage: update-management-wiki.sh -u apache_username:apache_password"
+    echo '  -u   Your id.apache.org creds in the form user:pass.  You can also set $APACHE_CREDS'
+    exit 1
+}
+
+while getopts ":u:" opt; do
+  case ${opt} in
+    u )
+      APACHE_CREDS=$OPTARG
+      ;;
+    \? )
+      usage
+      ;;
+  esac
+done
+
+if [[ "${APACHE_CREDS}" == "" ]] ; then
+    usage
+fi
+
+if [[ "${APACHE_CREDS}" =~ : ]]; then
+    true
+else
+    echo "Please specify creds in the form user:pass"
+    exit 1
+fi
+
+BRANCH=$(git rev-parse --abbrev-ref HEAD)
+if [[ ${BRANCH} != "develop" ]] && [[ ${BRANCH} != "master" ]] ; then
+    echo "Please git checkout develop or git checkout master before running this script"
+    exit 1
+fi
+
+MASTER_PAGE_ID=115511910
+DEVELOP_PAGE_ID=132322415
+[[ "${BRANCH}" == "master" ]] && PAGE_ID=$MASTER_PAGE_ID || PAGE_ID=$DEVELOP_PAGE_ID
+
+echo ""
+echo "============================================================"
+echo "Building"
+echo "============================================================"
+set -x
+(cd ${0%/*}/../../../.. && ./gradlew build installDist -x test -x javadoc -x rat -x pmdMain -x pmdTest)
+set +x
+
+GEODE=$(cd ${0%/*}/../../../../geode-assembly/build/install/apache-geode; pwd)
+
+if [ -x "$GEODE/bin/gfsh" ] ; then
+    true
+else
+    echo "gfsh not found"
+    exit 1
+fi
+
+echo ""
+echo "============================================================"
+echo "Checking that swagger-codegen is installed"
+echo "============================================================"
+brew install swagger-codegen || true
+brew upgrade swagger-codegen || true
+
+echo ""
+echo "============================================================"
+echo "Starting up a locator to access swagger"
+echo "============================================================"
+set -x
+ps -ef | grep swagger-locator | grep java | awk '{print $2}' | xargs kill -9
+[[ "${BRANCH}" == "master" ]] && GEODE_VERSION=$($GEODE/bin/gfsh version) || GEODE_VERSION=develop
+$GEODE/bin/gfsh "start locator --name=swagger-locator"
+set +x
+
+echo ""
+echo "============================================================"
+echo "Generating docs"
+echo "============================================================"
+set -x
+swagger-codegen generate -i http://localhost:7070/management${URI_VERSION}/api-docs -l html -o static
+set +x
+
+echo ""
+echo "============================================================"
+echo "Uploading to wiki"
+echo "============================================================"
+# step 1a: strip out body/header/html envelope
+# step 1b: add line breaks in code examples, since otherwise they inexplicably get lost in the upload
+# step 1c: escape quotes and newlines
+# step 1d: future: do any search-and-replaces to make it prettier here, such as to make up for lost css
+VALUE=$(cat static/index.html | awk '
+  /<\/body>/ {inbody=0}
+  inbody==1  {print}
+  /<body>/   {inbody=1}
+' | awk '
+  /<pre class="example"><code>/ {incode=1}
+  incode==1  {print $0"<br/>"}
+  incode!=1  {print}
+  /<\/code>/ {incode=0}
+' | sed 's/"/\\"/g')
+# step 2: get the current page version and ADD 1
+PAGE_VERSION=$(curl -s -u $APACHE_CREDS https://cwiki.apache.org/confluence/rest/api/content/${PAGE_ID} | jq .version.number)
+NEW_PAGE_VERSION=$(( PAGE_VERSION + 1 ))
+# step 3: insert as value into json update message
+TITLE="${GEODE_VERSION} Management REST API - ${URI_VERSION#/}"
+cat << EOF > body.json
+{
+  "id": "${PAGE_ID}",
+  "type": "page",
+  "title": "${TITLE}",
+  "space": {
+    "key": "GEODE"
+  },
+  "body": {
+    "storage": {
+      "value": "${VALUE}",
+      "representation": "storage"
+    }
+  },
+  "version": {
+    "number": ${NEW_PAGE_VERSION},
+    "minorEdit": true,
+    "message": "automatically generated from ${GEODE_VERSION} by update-management-wiki.sh"
+  }
+}
+EOF
+#step 4: upload to the wiki
+set -x
+curl -u $APACHE_CREDS -X PUT -H 'Content-Type: application/json' -d @body.json https://cwiki.apache.org/confluence/rest/api/content/${PAGE_ID}
+set +x
+
+echo ""
+echo "============================================================"
+echo "Cleaning up"
+echo "============================================================"
+set -x
+ps -ef | grep swagger-locator | grep java | awk '{print $2}' | xargs kill -9
+rm -Rf swagger-locator
+rm -Rf static
+rm body.json
+set +x
+
+# open your web browser to the newly-updated page
+open "https://cwiki.apache.org/confluence/display/pages/viewpage.action?pageId=${PAGE_ID}"
\ No newline at end of file